├── BP ├── Notes.md └── mediatek_dbginfo.ksy ├── COPYING.txt ├── DSP ├── .gitignore ├── MD32 │ ├── Notes.md │ ├── README.md │ ├── find_16bit_instructions.py │ ├── find_instructions.py │ ├── instruction_info.py │ ├── md32-binutils │ │ ├── .gitignore │ │ └── README.md │ ├── md32_dis.py │ └── swap_endian.py ├── Makefile ├── Notes.md ├── README.md ├── disasm.py ├── extract_fw.py ├── hd_be.sh ├── hd_be_decimal.py ├── hd_le.sh ├── hd_le_decimal.sh ├── mediatek_dbginfo_dsp.ksy ├── mediatek_lte_dsp_firmware.ksy └── mediatek_lte_dsp_firmware_v2.ksy ├── Documents.md ├── General-Notes.adoc ├── README.md ├── SoC ├── MT6735 │ ├── Notes.md │ ├── README.md │ ├── boot.sh │ ├── bootimg │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.sh │ │ ├── dump │ │ │ ├── .gitignore │ │ │ └── README.md │ │ └── ramdisk │ │ │ ├── .gitignore │ │ │ ├── 0001-disable-modem-init.patch │ │ │ ├── build.sh │ │ │ └── rebuild.sh │ ├── dump-to-bin.py │ ├── dump.sh │ ├── dump │ │ ├── .gitignore │ │ ├── Makefile │ │ └── dump.c │ ├── dump_md_debug_registers.sh │ ├── dump_md_smem.sh │ ├── kernel │ │ ├── .gitignore │ │ ├── 0001-fix-build.patch │ │ ├── 0002-enable-ccci-debug.patch │ │ ├── 0003-disable-dsp-memory-region-protection.patch │ │ ├── 0004-enable-wmt-debug.patch │ │ ├── 0005-fix-wmt_dev_dbg_write.patch │ │ ├── 0006-config.patch │ │ ├── README.md │ │ ├── build.sh │ │ └── rebuild.sh │ ├── md_dump.sh │ ├── md_poke.sh │ ├── md_poke │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── common.c │ │ ├── common.h │ │ ├── md_dump.c │ │ └── md_poke.c │ ├── modemfw │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── init.S │ │ ├── make_img.py │ │ ├── modem.ld │ │ ├── test.c │ │ └── vectors.S │ ├── mt6735.cfg │ ├── openocd.cfg │ ├── poke.sh │ ├── poke │ │ ├── .gitignore │ │ ├── Makefile │ │ └── poke.c │ ├── sd-jtag.sh │ ├── start-android-test-settings.sh │ └── start-engineer-mode.sh ├── MT6737M │ ├── README.md │ ├── dump │ ├── dump.sh │ ├── poke │ ├── poke.sh │ └── preloader │ │ ├── 0001-fix-build.patch │ │ ├── 0002-disable-BROM-lockout.patch │ │ ├── 0003-JTAG-over-SD-pins.patch │ │ └── README.md ├── MT6771 │ └── mt8183_pcm_allinone.ksy ├── MT8183 ├── common │ ├── README.md │ ├── bmo.py │ ├── demo │ │ ├── Makefile │ │ ├── hello-aarch64 │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── build_info.inc.c │ │ │ ├── init.S │ │ │ ├── linker.ld │ │ │ └── main.c │ │ ├── mode-switch │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── init.S │ │ │ ├── linker.ld │ │ │ └── main.c │ │ └── write-sequence │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── linker.ld │ │ │ └── write-sequence.S │ ├── doc │ │ ├── BROM-Notes.md │ │ └── README.md │ ├── gcpu.py │ ├── handshake │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README.md │ │ └── handshake.c │ ├── init.py │ ├── make_image.py │ ├── md32.py │ ├── openocd.py │ ├── parse_brom_log.py │ ├── parse_efuses.py │ ├── pcm.py │ ├── socemu.py │ └── usbdl.py ├── mediatek_download_agent.ksy └── mediatek_preloader.ksy └── Tasks.md /BP/Notes.md: -------------------------------------------------------------------------------- 1 | # BP Notes 2 | 3 | 4 | ## Firmware 5 | 6 | * File name is `modem.img`, which can be found in `/system/etc/firmware` 7 | on the device filesystem. 8 | * The firmware file is loaded by the kernel in 9 | `drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c` after being 10 | triggered by `/system/bin/ccci_mdinit 0` (where "0" is the index of 11 | the modem you want to run the code on). 12 | * Debug symbols for the modem code can be found in `/system/etc/mddb` in 13 | a file with a name that starts with `DbgInfo`. 14 | * The format of this file is described in the Kaitai Struct definition 15 | file [mediatek_dbginfo.ksy](mediatek_dbginfo.ksy). 16 | -------------------------------------------------------------------------------- /BP/mediatek_dbginfo.ksy: -------------------------------------------------------------------------------- 1 | meta: 2 | id: mediatek_dbginfo 3 | endian: le 4 | title: MediaTek Modem Debug Info 5 | license: CC0-1.0 6 | seq: 7 | - id: header 8 | type: header 9 | instances: 10 | symbols: 11 | type: symbols 12 | pos: header.symbols_start 13 | size: header.file_associations_start - header.symbols_start - 1 14 | file_associations: 15 | type: file_associations 16 | pos: header.file_associations_start 17 | size: _io.size - header.file_associations_start - 1 18 | types: 19 | header: 20 | seq: 21 | - id: magic 22 | type: str 23 | size: 4 24 | encoding: ASCII 25 | - id: ver 26 | type: u4 27 | - id: unk 28 | type: u4 29 | - id: version 30 | type: strz 31 | encoding: ASCII 32 | - id: platform 33 | type: strz 34 | encoding: ASCII 35 | - id: build_name 36 | type: strz 37 | encoding: ASCII 38 | - id: build_time 39 | type: strz 40 | encoding: ASCII 41 | - id: symbols_start 42 | type: u4 43 | - id: file_associations_start 44 | type: u4 45 | symbols: 46 | seq: 47 | - id: symbol 48 | type: symbol 49 | repeat: eos 50 | symbol: 51 | seq: 52 | - id: name 53 | type: strz 54 | encoding: ASCII 55 | - id: start 56 | type: u4 57 | - id: end 58 | type: u4 59 | file_associations: 60 | seq: 61 | - id: file_association 62 | type: file_association 63 | repeat: eos 64 | file_association: 65 | seq: 66 | - id: file 67 | type: strz 68 | encoding: UTF-8 69 | - id: range_count 70 | type: u4 71 | - id: symbol_range 72 | type: symbol_range 73 | repeat: expr 74 | repeat-expr: range_count 75 | symbol_range: 76 | seq: 77 | - id: start 78 | type: u4 79 | - id: end 80 | type: u4 81 | -------------------------------------------------------------------------------- /DSP/.gitignore: -------------------------------------------------------------------------------- 1 | mediatek_lte_dsp_firmware.py 2 | *.bin 3 | -------------------------------------------------------------------------------- /DSP/MD32/Notes.md: -------------------------------------------------------------------------------- 1 | # MD32 CPU/ISA 2 | 3 | * 16/32-bit big-endian instructions. 4 | * Instructions are stored little-endian byte order in the DSP blobs and in 5 | the VPU firmware binary. 6 | * All instructions are aligned on 2-byte boundaries. 7 | * 16 32-bit registers. 8 | * `r14` appears to be used as the stack pointer. 9 | * `r15` appears to be used as the link register. 10 | * Including the reset vector (zero), the vector table looks like it has at 11 | least 16 slots. 12 | * Stack seems to grow upward, though that doesn't appear to be hard-coded. 13 | * Separate program and data memory address spaces. 14 | -------------------------------------------------------------------------------- /DSP/MD32/README.md: -------------------------------------------------------------------------------- 1 | # MD32 2 | 3 | This directory contains tools for reverse engineering the MD32 ISA, as well as 4 | some [reverse engineering notes][notes] about the CPU/ISA. 5 | 6 | Binaries can be disassembled and decompiled using [Ghidra][ghidra] with the 7 | [MD32 Ghidra processor module][ghidra-md32]. 8 | 9 | 10 | ## find_instructions.py 11 | 12 | Use this tool to identify the opcodes and opcode bitmasks for each 13 | instruction. The [Z3 theorem prover][z3] is used to help generate instructions 14 | to feed into the disassembler. 15 | 16 | 17 | ## find_16bit_instructions.py 18 | 19 | This tool will search through the 16-bit instruction space of the MD32 to find 20 | and define decoding rules for each instruction. Like `find_instructions.py`, 21 | this script also uses [Z3][z3], but instead of using it to generate 22 | instructions, it uses Z3 to prove the correctness of the generated 23 | instruction-decoding rules. 24 | 25 | 26 | ## instruction_info.py 27 | 28 | This tool will print a nice summary of the instructions you've found with 29 | `find_instructions.py`. 30 | 31 | 32 | ## md32_dis.py 33 | 34 | This is the Python module that wraps the MD32's `objdump` binary, to make it 35 | easier to dynamically disassemble arbitrary instructions. 36 | 37 | 38 | ## swap_endian.py 39 | 40 | Use this to swap the endianness of an MD32 binary. The VPU firmware binaries 41 | distributed in linux-firmware and the binaries extrated from the DSP binary 42 | file are all in little-endian form, but the MD32 parses instructions in 43 | big-endian byte order, so you need to run `swap_endian.py` on these files 44 | before disassembly in order to correct for this. 45 | 46 | 47 | [notes]: Notes.md 48 | [ghidra]: https://github.com/NationalSecurityAgency/ghidra 49 | [ghidra-md32]: https://github.com/cyrozap/ghidra-md32 50 | [z3]: https://github.com/Z3Prover/z3 51 | -------------------------------------------------------------------------------- /DSP/MD32/find_16bit_instructions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # find_16bit_instructions.py - A tool to intelligently discover 16-bit MD32 5 | # instructions using its disassembler binary. 6 | # Copyright (C) 2020-2021 Forest Crossman 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | import argparse 23 | import json 24 | import multiprocessing 25 | import os 26 | 27 | from z3 import * 28 | 29 | from md32_dis import Instruction, disassemble_dword 30 | 31 | 32 | def process_dword(dword): 33 | disassembled = disassemble_dword(dword) 34 | if disassembled is None: 35 | return None 36 | 37 | if not isinstance(disassembled, Instruction): 38 | # We're not testing instruction bundles. 39 | return None 40 | 41 | if disassembled.size > 2: 42 | # We're not testing 32-bit instructions. 43 | #print("Not testing {}.".format(mnemonic)) 44 | return None 45 | 46 | args = disassembled.args 47 | argfmt = None 48 | if args: 49 | argfmt = type(args).__name__ 50 | if not argfmt: 51 | raise ValueError("Unknown argument format: \"{}\"".format(args)) 52 | 53 | return (disassembled.value, disassembled.mnemonic, argfmt) 54 | 55 | def main(): 56 | parser = argparse.ArgumentParser() 57 | parser.add_argument("instructions", type=str, help="The JSON file with the list of instructions you want to read/write.") 58 | arguments = parser.parse_args() 59 | 60 | opcodes = set() 61 | 62 | processes = os.cpu_count() 63 | chunk_size = 16 64 | 65 | with multiprocessing.Pool(processes) as pool: 66 | print("Generating candidates...") 67 | candidates = pool.imap_unordered(process_dword, range(0x8000 << 16, 1 << 32, 1 << 16), chunk_size) 68 | 69 | instruction_map = dict() 70 | for instr, mnemonic, argfmt in filter(lambda x: x != None, candidates): 71 | if instruction_map.get((mnemonic, argfmt)) is None: 72 | instruction_map[(mnemonic, argfmt)] = set() 73 | instruction_map[(mnemonic, argfmt)].add(instr) 74 | 75 | for (mnemonic, argfmt), instrs in instruction_map.items(): 76 | instr = BitVec("instr", 32) 77 | 78 | actual = [] 79 | for i in instrs: 80 | actual.append(instr == BitVecVal(i, 32)) 81 | actual = Or(actual) 82 | 83 | model = [] 84 | model.append((instr & 0x0000ffff) == BitVecVal(0, 32)) 85 | model.append(ULE(instr, max(instrs))) 86 | model.append(UGE(instr, min(instrs))) 87 | model = And(model) 88 | 89 | #print("{} ({}): {}".format(mnemonic, argfmt, simplify(actual))) 90 | print("{} ({}): {}".format(mnemonic, argfmt, simplify(model))) 91 | 92 | s = Solver() 93 | s.push() 94 | s.add(Not(actual == model)) 95 | if s.check() == sat: 96 | print("Error: Model does not match reality. Counterexample: instr = 0x{:08x}".format(s.model()[instr].as_long())) 97 | 98 | s.push() 99 | counterexamples = set() 100 | while s.check() == sat: 101 | counterexample = s.model()[instr].as_long() 102 | counterexamples.add(counterexample) 103 | s.add(instr != BitVecVal(counterexample, 32)) 104 | s.pop() 105 | 106 | # Split the instruction definition. 107 | s.pop() 108 | new_model = And( 109 | (instr & 0x0000ffff) == BitVecVal(0, 32), 110 | Or( 111 | And( 112 | ULE(instr, max(instrs)), 113 | UGT(instr, max(counterexamples)), 114 | ), 115 | And( 116 | ULT(instr, min(counterexamples)), 117 | UGE(instr, min(instrs)), 118 | ), 119 | ), 120 | ) 121 | s.add(Not(actual == new_model)) 122 | 123 | if s.check() == sat: 124 | print("Error: Still not equal. Counterexample: instr = 0x{:08x}".format(s.model()[instr].as_long())) 125 | continue 126 | 127 | print("Found new model: {} ({}): {}".format(mnemonic, argfmt, simplify(new_model))) 128 | opcodes.add((mnemonic, argfmt, min(instrs), min(counterexamples) - (1 << 16))) 129 | opcodes.add((mnemonic, argfmt, max(counterexamples) + (1 << 16), max(instrs))) 130 | continue 131 | 132 | opcodes.add((mnemonic, argfmt, min(instrs), max(instrs))) 133 | 134 | opcodes_file = open(args.instructions, 'w') 135 | json.dump(list(opcodes), opcodes_file) 136 | opcodes_file.close() 137 | 138 | print("Done!") 139 | 140 | 141 | if __name__ == "__main__": 142 | main() 143 | -------------------------------------------------------------------------------- /DSP/MD32/find_instructions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # find_instructions.py - A tool to intelligently discover 32-bit MD32 5 | # instructions using its disassembler binary. 6 | # Copyright (C) 2020-2021 Forest Crossman 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | import argparse 23 | import json 24 | import os 25 | import struct 26 | import time 27 | 28 | from z3 import * 29 | 30 | from md32_dis import Instruction, disassemble_dword 31 | 32 | 33 | class Opcodes: 34 | def __init__(self): 35 | self.opcode_set = set() 36 | 37 | def __iter__(self): 38 | return self.opcode_set.__iter__() 39 | 40 | def add(self, mnemonic, argfmt, mask, opcode): 41 | self.opcode_set.add((mnemonic, argfmt, mask, opcode)) 42 | 43 | def get_by_mnemonic_and_argfmt(self, mnemonic, argfmt): 44 | for (mn, af, mask, opcode) in self.opcode_set: 45 | if mnemonic == mn and argfmt == af: 46 | return (mn, af, mask, opcode) 47 | return None 48 | 49 | def get_by_mnemonic_and_instr(self, mnemonic, instr): 50 | for (mn, argfmt, mask, opcode) in self.opcode_set: 51 | if (instr & mask) == opcode and mnemonic == mn: 52 | return (mn, argfmt, mask, opcode) 53 | return None 54 | 55 | def get_by_instr(self, instr): 56 | for (mn, argfmt, mask, opcode) in self.opcode_set: 57 | if (instr & mask) == opcode: 58 | return (mn, argfmt, mask, opcode) 59 | return None 60 | 61 | 62 | def main(): 63 | parser = argparse.ArgumentParser() 64 | parser.add_argument("-t", "--timeout", type=float, default=1, help="The number of seconds to wait for Z3 to generate an instruction before trying a random one.") 65 | parser.add_argument("instructions", type=str, help="The JSON file with the list of instructions you want to read/write.") 66 | arguments = parser.parse_args() 67 | 68 | s = Solver() 69 | 70 | instr = BitVec("instr", 32) 71 | 72 | timeout = arguments.timeout 73 | 74 | extra_seeds = set() 75 | 76 | opcodes = Opcodes() 77 | try: 78 | opcodes_file = open(arguments.instructions, 'r') 79 | opcode_list = json.load(opcodes_file) 80 | opcodes_file.close() 81 | 82 | print("Loaded saved results:") 83 | for (mnemonic, argfmt, mask, opcode) in opcode_list: 84 | opcodes.add(mnemonic, argfmt, mask, opcode) 85 | print("{} ({}): mask = 0x{:08x}, masked opcode = 0x{:08x}".format(mnemonic, argfmt, mask, opcode)) 86 | s.add((instr & BitVecVal(mask, 32)) != BitVecVal(opcode, 32)) 87 | 88 | # Add extra instruction seeds. 89 | candidate_bits = set(range(32)) 90 | while candidate_bits: 91 | candidate = candidate_bits.pop() 92 | test_instr = opcode ^ (1 << candidate) 93 | test_dis = disassemble_dword(test_instr) 94 | if not test_dis or not isinstance(test_dis, Instruction): 95 | continue 96 | new_args = test_dis.args 97 | new_argfmt = None 98 | if new_args: 99 | new_argfmt = type(new_args).__name__ 100 | new_mnemonic = test_dis.mnemonic 101 | if new_argfmt and opcodes.get_by_mnemonic_and_argfmt(new_mnemonic, new_argfmt) and opcodes.get_by_instr(test_instr): 102 | continue 103 | extra_seeds.add(test_instr) 104 | except (FileNotFoundError, json.decoder.JSONDecodeError): 105 | pass 106 | 107 | while s.check() == sat: 108 | # First, obtain a "seed" instruction. Time out and use a random seed if Z3 is too slow. 109 | start = time.monotonic() 110 | mnemonic = None 111 | while True: 112 | disassembled = None 113 | while not disassembled: 114 | if extra_seeds: 115 | seed = extra_seeds.pop() 116 | elif time.monotonic() - start > timeout: 117 | #print("Using random seed due to timeout.") 118 | seed = struct.unpack('>I', os.urandom(4))[0] 119 | start = time.monotonic() 120 | else: 121 | try: 122 | #print("Using Z3 seed.") 123 | seed = s.model()[instr].as_long() 124 | except (AttributeError, Z3Exception): 125 | # Use a random value the first time. 126 | #print("Using random seed.") 127 | seed = struct.unpack('>I', os.urandom(4))[0] 128 | 129 | disassembled = disassemble_dword(seed) 130 | 131 | # We don't ever want Z3 to give us this seed again. 132 | s.add(instr != BitVecVal(seed, 32)) 133 | 134 | # Check the model to "commit" the result. 135 | s.check() 136 | 137 | if not isinstance(disassembled, Instruction): 138 | # We're not testing instruction bundles. 139 | print("Not testing {}.".format(disassembled)) 140 | continue 141 | instr_size = disassembled.size 142 | mnemonic = disassembled.mnemonic 143 | if instr_size < 4: 144 | # We're not testing 16-bit instructions yet. 145 | print("Not testing {}.".format(mnemonic)) 146 | continue 147 | args = disassembled.args 148 | argfmt = None 149 | if args: 150 | argfmt = type(args).__name__ 151 | opcode_item = None 152 | if argfmt: 153 | opcode_item = opcodes.get_by_mnemonic_and_argfmt(mnemonic, argfmt) 154 | if opcode_item and opcodes.get_by_instr(seed): 155 | # Don't test instructions we've already tested. 156 | print("Already tested {0} ({1}) (mask = 0x{2:08x}, masked opcode = 0x{3:08x}).".format(*opcode_item)) 157 | continue 158 | 159 | break 160 | 161 | print("Seed instruction: 0x{:08x} ({})".format(seed, mnemonic)) 162 | 163 | # For each bit in the instruction, flip it, then try decoding the 164 | # instruction again. If it decodes to the same mnemonic, then that bit 165 | # is not essential to decoding the instruction. If it decodes to a 166 | # different mnemonic, then that bit is essential to decoding the 167 | # instruction. If we run out of candidate bits, then we're done--use 168 | # Z3 to find us another instruction that doesn't match this one. 169 | 170 | candidate_bits = set(range(32)) 171 | 172 | unessential_bits = set() 173 | 174 | while candidate_bits: 175 | candidate = candidate_bits.pop() 176 | test_instr = seed ^ (1 << candidate) 177 | test_dis = disassemble_dword(test_instr) 178 | if not test_dis or not isinstance(test_dis, Instruction): 179 | continue 180 | new_args = test_dis.args 181 | new_argfmt = None 182 | if new_args: 183 | new_argfmt = type(new_args).__name__ 184 | new_mnemonic = test_dis.mnemonic 185 | if new_mnemonic != mnemonic or new_argfmt != argfmt: 186 | if not new_argfmt or not opcodes.get_by_mnemonic_and_argfmt(new_mnemonic, new_argfmt) or not opcodes.get_by_instr(test_instr): 187 | # Found a new opcode? 188 | extra_seeds.add(test_instr) 189 | continue 190 | unessential_bits.add(candidate) 191 | 192 | essential_bits = set(range(32)).difference(unessential_bits) 193 | 194 | # Generate an opcode mask and value for the mnemonic. 195 | op_mask = 0 196 | while essential_bits: 197 | bit = essential_bits.pop() 198 | op_mask |= 1 << bit 199 | op_value = op_mask & seed 200 | 201 | if not argfmt: 202 | print("Error: Unknown argument format: \"{}\"".format(disassembled[3])) 203 | return 204 | 205 | opcodes.add(mnemonic, argfmt, op_mask, op_value) 206 | 207 | print("{} ({}): mask = 0x{:08x}, masked opcode = 0x{:08x}".format(mnemonic, argfmt, op_mask, op_value)) 208 | 209 | s.add((instr & BitVecVal(op_mask, 32)) != BitVecVal(op_value, 32)) 210 | 211 | opcodes_file = open(arguments.instructions, 'w') 212 | json.dump(list(opcodes), opcodes_file) 213 | opcodes_file.close() 214 | 215 | print("Done!") 216 | 217 | 218 | if __name__ == "__main__": 219 | main() 220 | -------------------------------------------------------------------------------- /DSP/MD32/instruction_info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2020 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | import argparse 20 | import json 21 | 22 | 23 | def count_mask_prefix_bits(mask): 24 | bits = 0 25 | for i in range(32)[::-1]: 26 | if mask & (1 << i) == 0: 27 | break 28 | bits += 1 29 | return bits 30 | 31 | def main(): 32 | parser = argparse.ArgumentParser() 33 | parser.add_argument("instructions", type=str, help="The JSON file with instructions you want to parse.") 34 | args = parser.parse_args() 35 | 36 | opcodes_file = open(args.instructions, 'r') 37 | opcode_list = json.load(opcodes_file) 38 | opcodes_file.close() 39 | 40 | print("Instructions, sorted by mnemonic, then opcode:") 41 | for opcode in sorted(opcode_list, key=lambda e: (e[0], e[3])): 42 | print(" {0} ({1}): mask = 0x{2:08x}, masked opcode = 0x{3:08x}".format(*opcode)) 43 | 44 | print("Instructions, sorted by opcode, then mnemonic:") 45 | for opcode in sorted(opcode_list, key=lambda e: (e[3], e[0])): 46 | print(" {0} ({1}): mask = 0x{2:08x}, masked opcode = 0x{3:08x}".format(*opcode)) 47 | 48 | print("Instructions, sorted by mask prefix bits, then opcode:") 49 | for opcode in sorted(opcode_list, key=lambda e: (count_mask_prefix_bits(e[2]), e[3])): 50 | print(" {0} ({1}): mask = 0x{2:08x}, masked opcode = 0x{3:08x}".format(*opcode)) 51 | 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /DSP/MD32/md32-binutils/.gitignore: -------------------------------------------------------------------------------- 1 | as 2 | objcopy 3 | objdump 4 | -------------------------------------------------------------------------------- /DSP/MD32/md32-binutils/README.md: -------------------------------------------------------------------------------- 1 | # MD32 binutils 2 | 3 | Place the `objdump` binary from the MD32's binutils in this directory. 4 | 5 | The binary can be found in the Orange Pi 4G-IoT Android 8.1 source code 6 | archive (22 GB, available [here][download-page]). Please note that the MD32 7 | compiler and binutils are only available in the Android 8.1 archive, and not 8 | any of the other ones. Once you've downloaded the first part of the archive 9 | (`x00`, 2 GB), the binary can be extracted with the following command: 10 | 11 | ``` 12 | $ tar -xzf x00 OrangePi_4G-IOT_Android8.1/code/ccu_tool/md32ccu/ToolChain/install_md32/md32-elf/bin/objdump 13 | ``` 14 | 15 | Ignore the EOF errors in the `tar` output--this is to be expected since the 16 | `x00` file is not a complete tar archive. 17 | 18 | After extracting the binary, move it into this directory so the Python scripts 19 | can find it. 20 | 21 | 22 | [download-page]: http://www.orangepi.org/downloadresources/orangepi4G-IOT/2020-04-23/3928a702a73dfbce5554489a1f9e6edc.html 23 | -------------------------------------------------------------------------------- /DSP/MD32/swap_endian.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2020 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | import argparse 20 | import struct 21 | import sys 22 | 23 | 24 | def main(): 25 | parser = argparse.ArgumentParser(description="Swap the endianness of every 32-bit word in a file.") 26 | parser.add_argument("-o", "--output", type=str, help="The endian-swapped output binary.") 27 | parser.add_argument("input", type=str, help="The input binary.") 28 | args = parser.parse_args() 29 | 30 | binary = open(args.input, 'rb').read() 31 | 32 | output = sys.stdout.buffer 33 | if args.output: 34 | output = open(args.output, 'wb') 35 | 36 | for (word,) in struct.iter_unpack('I', word)) 38 | 39 | output.close() 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /DSP/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2017, 2020 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | all: mediatek_lte_dsp_firmware.py 19 | 20 | %.py: %.ksy 21 | kaitai-struct-compiler -t python $< 22 | -------------------------------------------------------------------------------- /DSP/Notes.md: -------------------------------------------------------------------------------- 1 | # DSP Notes 2 | 3 | 4 | ## ISA 5 | 6 | * 24-bit instructions 7 | * The code binary has a null byte after every three bytes, at a minimum. 8 | * It would be less complicated for every 32-bit word on the Cortex-R4 9 | side correspond to a 24-bit instruction word on the DSP side, since the 10 | DSP could use the same addressing scheme but with 8 fewer data lines. 11 | * Confirmed by [Coresonic's website][Coresonic]. 12 | 13 | 14 | ## Firmware 15 | 16 | * The firmware binary contains 7 firmware sections. 17 | * Each section has a code and data segment. 18 | * The max length of the code segment is 0x28000 32-bit words (0xA0000 19 | bytes). 20 | * The max length of the data segment is 0x6400 32-bit words (0x19000 21 | bytes). 22 | * Each segment has a checksum. 23 | * The checksum is simply the XOR of all the obfuscated 32-bit words in 24 | that segment. 25 | * Checksum verification can be disabled by setting the checksum to zero. 26 | * Each section contains the code and data for a single DSP core. 27 | * There are 7 DSP cores. 28 | * The cores are named as follows: 29 | * 1: FMC/FC1 30 | * 2: BC/BC1 31 | * 3: MC/MC1 32 | * 4: FNC/FC2 33 | * 5: MMC/MC2 34 | * 6: MSC/MC3 35 | * 7: MD32 36 | * MD32, the 7th core (`core_idx` 7) seems to be different from the other 37 | cores. 38 | * Its code segment cotains 32-bit instructions. 39 | * The code and data are loaded into a separate region of the Cortex-R4's 40 | address space compared to the other 6 cores. 41 | * It's possible that this is a [MediaDSP][MediaDSP] core used for audio 42 | coding. 43 | * The register tables for multiple SoCs heavily imply this. 44 | * Also might be [this][devicetree-bindings]. 45 | * They might use it for different purposes in different SoCs. 46 | * Each section is loaded sequentially based on its location in the binary. 47 | * In other words, they're loaded in `file_idx` order, not `core_idx` 48 | order. 49 | 50 | 51 | [Coresonic]: https://web.archive.org/web/20120415124337/http://www.coresonic.com/12/Products/Technology.html 52 | [MediaDSP]: https://www.da.isy.liu.se/pubs/diwu/diwu-ssocc2006.pdf 53 | [devicetree-bindings]: https://github.com/freedomtan/kernel-3.18-X20-96-board/blob/a0fd09200a4a4f7de5d366d20e43027f8dc6709a/Documentation/devicetree/bindings/misc/mediatek-md32.txt 54 | -------------------------------------------------------------------------------- /DSP/README.md: -------------------------------------------------------------------------------- 1 | # Coresonic (MediaTek) DSP code 2 | 3 | 4 | ## Quick start 5 | 6 | Software dependencies: 7 | 8 | * Python 3 9 | * [Kaitai Struct Compiler][ksc] 10 | * [Kaitai Struct Python Runtime][kspr] 11 | 12 | To start looking at the DSP code, you'll need a DSP binary. You can find 13 | these on a MediaTek LTE baseband-based phone in `/system/etc/firmware`, and 14 | the file will be called something like `dsp_*.bin`. If you don't have access 15 | to a phone with a MediaTek LTE modem, you can also find these firmware files 16 | on the Internet, typically in the "vendor.zip" files posted by Android ROM 17 | developers. You can also find them, for example, using 18 | [this GitHub search query][firmware query]. Note: You must be logged in to 19 | GitHub in order to get any results from that query. 20 | 21 | Once you have the DSP binary, run `make` in this directory to generate the 22 | parser code used by `extract_fw.py`. Then, simply run 23 | `./extract_fw.py dsp_*.bin` to extract each section from the binary into 24 | separate files. 25 | 26 | To verify that the DSP binary has been parsed correctly, run 27 | `strings -e l *.data.bin` and make sure that some human-readable text 28 | strings are output. You should see some file paths, build IDs, and build 29 | timestamps at the very least. For additional confirmation, all the code 30 | binaries (`*.code.bin`) except for `*.core_idx_7.code.bin` should have every 31 | fourth byte set to zero, which will be very noticeable in a hex dump. 32 | 33 | 34 | ## Notes 35 | 36 | See [Notes.md](Notes.md). 37 | 38 | 39 | [ksc]: https://github.com/kaitai-io/kaitai_struct_compiler 40 | [kspr]: https://github.com/kaitai-io/kaitai_struct_python_runtime 41 | [firmware query]: https://github.com/search?q=filename%3Adsp_1_lwg_n.bin 42 | -------------------------------------------------------------------------------- /DSP/disasm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2021 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | import argparse 20 | import struct 21 | 22 | 23 | class InstDecodeError(Exception): 24 | pass 25 | 26 | 27 | def dis(instr : int): 28 | # Instructions are all 24 bits wide. 29 | if instr >> 24 != 0: 30 | raise InstDecodeError("Instruction 0x{:08x} wider than 32 bits.".format(instr)) 31 | 32 | bits = "{:024b}".format(instr) 33 | 34 | return bits 35 | 36 | def main(): 37 | parser = argparse.ArgumentParser() 38 | parser.add_argument("firmware", type=str, help="The firmware binary.") 39 | args = parser.parse_args() 40 | 41 | fw = open(args.firmware, 'rb').read() 42 | 43 | for (instr,) in struct.iter_unpack(' 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import argparse 22 | import struct 23 | import sys 24 | 25 | try: 26 | import mediatek_lte_dsp_firmware 27 | except ModuleNotFoundError: 28 | sys.stderr.write("Error: Failed to import \"mediatek_lte_dsp_firmware.py\". Please run \"make\" in this directory to generate that file, then try running this script again.\n") 29 | sys.exit(1) 30 | 31 | key = bytes([0x40, 0xeb, 0xf8, 0x56, 0x8b, 0x74, 0x24, 0x08, 0x66, 0x85, 0xf6, 0x74, 0x30, 0x66, 0x83, 0xfe]) 32 | 33 | def checksum_valid(data, checksum): 34 | if checksum == 0: 35 | return True 36 | 37 | temp = 0 38 | for i in range(len(data)//4): 39 | temp ^= struct.unpack_from(' 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | hexdump -e '"0x%08_ax |" 4/1 "%02x" "|\n"' $@ 20 | -------------------------------------------------------------------------------- /DSP/hd_be_decimal.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | import sys 20 | 21 | if __name__ == "__main__": 22 | old = open(sys.argv[1], 'rb').read() 23 | for i in range(0, len(old), 4): 24 | number = old[i] << 16 | old[i+1] << 8 | old[i+2] 25 | print(number) 26 | -------------------------------------------------------------------------------- /DSP/hd_le.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | hexdump -e '"0x%08_ax |" 1/4 "%08x" "|\n"' $@ 20 | -------------------------------------------------------------------------------- /DSP/hd_le_decimal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | hexdump -v -e '1/4 "%d\n"' $@ 20 | -------------------------------------------------------------------------------- /DSP/mediatek_dbginfo_dsp.ksy: -------------------------------------------------------------------------------- 1 | meta: 2 | id: mediatek_dbginfo_dsp 3 | endian: le 4 | title: MediaTek Debug Info for DSP 5 | license: CC0-1.0 6 | seq: 7 | - id: magic 8 | contents: "CATICTNR" 9 | - id: ver 10 | type: u4 11 | - id: footer_offset 12 | type: u4 13 | instances: 14 | footer: 15 | pos: footer_offset 16 | type: footer 17 | types: 18 | dbginfo: 19 | seq: 20 | - id: header 21 | type: header 22 | instances: 23 | symbols: 24 | pos: _parent.offset + header.symbols_start 25 | type: symbols 26 | size: header.file_associations_start - header.symbols_start - 1 27 | file_associations: 28 | pos: _parent.offset + header.file_associations_start 29 | type: file_associations 30 | # size: _parent.len - 16 - header.file_associations_start - 1 31 | types: 32 | header: 33 | seq: 34 | - id: magic 35 | contents: "CATI" 36 | - id: ver 37 | type: u4 38 | - id: unk 39 | type: u4 40 | - id: version 41 | type: strz 42 | encoding: "ASCII" 43 | - id: platform 44 | type: strz 45 | encoding: "ASCII" 46 | - id: build_name 47 | type: strz 48 | encoding: "ASCII" 49 | - id: build_time 50 | type: strz 51 | encoding: "ASCII" 52 | - id: symbols_start 53 | type: u4 54 | - id: file_associations_start 55 | type: u4 56 | symbols: 57 | seq: 58 | - id: symbol 59 | type: symbol 60 | repeat: eos 61 | types: 62 | symbol: 63 | seq: 64 | - id: name 65 | type: strz 66 | encoding: "ASCII" 67 | - id: start 68 | type: u4 69 | - id: end 70 | type: u4 71 | file_associations: 72 | seq: 73 | - id: file_association 74 | type: file_association 75 | repeat: expr 76 | repeat-expr: 30 # Arbitrary limit because the array of file associations is null-terminated and Kaitai Struct doesn't have any "repeat until null" functionality. 77 | types: 78 | file_association: 79 | seq: 80 | - id: file 81 | type: strz 82 | encoding: "UTF-8" 83 | - id: range_count 84 | type: u4 85 | - id: symbol_range 86 | type: 87 | switch-on: _parent._parent.header.ver 88 | cases: 89 | 1: symbol_range_v1 90 | 2: symbol_range_v2 91 | repeat: expr 92 | repeat-expr: range_count 93 | types: 94 | symbol_range_v1: 95 | seq: 96 | - id: start 97 | type: u4 98 | - id: end 99 | type: u4 100 | symbol_range_v2: 101 | seq: 102 | - id: start 103 | type: u4 104 | - id: end 105 | type: u4 106 | - id: unk3 107 | type: u4 108 | footer: 109 | seq: 110 | - id: section_count 111 | type: u4 112 | - id: sections 113 | type: section 114 | repeat: expr 115 | repeat-expr: section_count 116 | types: 117 | section: 118 | seq: 119 | - id: offset 120 | type: u4 121 | - id: name 122 | type: strz 123 | encoding: "ASCII" 124 | - id: unk3 125 | type: strz 126 | encoding: "ASCII" 127 | instances: 128 | dbginfo: 129 | io: _root._io 130 | pos: offset 131 | type: dbginfo 132 | -------------------------------------------------------------------------------- /DSP/mediatek_lte_dsp_firmware.ksy: -------------------------------------------------------------------------------- 1 | meta: 2 | id: mediatek_lte_dsp_firmware 3 | endian: le 4 | title: MediaTek LTE modem DSP firmware 5 | license: CC0-1.0 6 | application: Firmware image LTE modem DSP 7 | doc: Firmware image for the Coresonic DSP found in MediaTek LTE modems. 8 | seq: 9 | - id: gfh_file_info 10 | type: gfh_file_info 11 | - id: gfh_dsp_info 12 | type: gfh_dsp_info 13 | - id: dsp_firmware 14 | type: dsp_firmware 15 | size: gfh_file_info.file_len - gfh_file_info.content_offset 16 | enums: 17 | gfh_file_type: 18 | # recognized by bootrom 19 | 0x0000: gfh_file_none 20 | 0x0001: arm_bl 21 | 0x0002: arm_ext_bl 22 | 0x0003: dualmac_dsp_bl 23 | 0x0004: sctrl_cert 24 | 0x0005: tool_auth 25 | 0x0006: file_mtk_reserved1 26 | 0x0007: epp 27 | 0x0008: file_mtk_reserved2 28 | 0x0009: file_mtk_reserved3 29 | 0x000a: root_cert 30 | 0x000b: ap_bl 31 | 32 | # maui binary group 33 | 0x0100: primary_maui 34 | 0x0101: secondary_maui 35 | 0x0102: on_demand_paging 36 | 0x0103: third_rom 37 | 0x0104: dsp_rom 38 | 0x0105: cached_dsp_rom 39 | 0x0106: primary_factory_bin 40 | 0x0107: secondary_factory_bin 41 | 0x0108: viva 42 | 0x0109: lte_dsp_rom 43 | 0x017f: v_maui_binary_end 44 | 45 | # resource binary group 46 | 0x0180: custom_pack 47 | 0x0181: language_pack 48 | 0x0182: jump_table 49 | 50 | # binary not belonging to maui 51 | 0x0200: fota_ue 52 | 0x0201: arm_ext_bl_backup 53 | 54 | # secure structure group 55 | 0x0300: secure_ro_s 56 | 0x0301: secure_ro_me 57 | 58 | # external_file 59 | 0x0400: card_download_package 60 | 0x0401: confidential_binary 61 | 62 | # file system 63 | 0x0480: file_system 64 | 65 | # secure structure group 66 | 0x500: boot_cert_ctrl 67 | 68 | # customized_file 69 | 0x7000: customer_bin1 70 | 0x7001: customer_bin2 71 | 0x7002: customer_bin3 72 | 73 | # slt_load_file 74 | 0x8000: gfh_file_type_for_mt6290 75 | gfh_flash_dev: 76 | 0: flash_dev_none 77 | 1: f_nor 78 | 2: f_nand_sequential 79 | 3: f_nand_ttbl 80 | 4: f_nand_fdm50 81 | 5: f_emmc_boot_region 82 | 6: f_emmc_data_region 83 | 7: f_sf 84 | 8: f_xboot 85 | gfh_sig_type: 86 | 0: sig_none 87 | 1: sig_phash 88 | 2: sig_single 89 | 3: sig_single_and_phash 90 | 4: sig_multi 91 | types: 92 | gfh_header: 93 | seq: 94 | - id: magic_ver 95 | type: magic_ver 96 | - id: size 97 | type: u2 98 | - id: type 99 | type: u2 100 | enum: gfh_type 101 | enums: 102 | gfh_type: 103 | 0x0000: gfh_file_info 104 | 0x0001: gfh_bl_info 105 | 0x0002: gfh_anti_clone 106 | 0x0003: gfh_bl_sec_key 107 | 0x0004: gfh_sctrl_cert 108 | 0x0005: gfh_tool_auth 109 | 0x0006: gfh_mtk_reserved1 110 | 0x0007: gfh_brom_cfg 111 | 0x0008: gfh_brom_sec_cfg 112 | 0x0009: gfh_mtk_reserved2 113 | 0x000a: gfh_mtk_reserved3 114 | 0x000b: gfh_root_cert 115 | 0x000c: gfh_exp_chk 116 | 0x000d: gfh_epp_param 117 | 0x000e: gfh_chip_ver 118 | 0x000f: gfh_mtk_reserved4 119 | 0x0010: gfh_md_sec_cfg 120 | 0x0100: gfh_epp_info 121 | 0x0101: gfh_emi_list 122 | 0x0102: gfh_cmem_id_info 123 | 0x0103: gfh_cmem_nor_info 124 | 0x0104: gfh_dsp_info 125 | 0x0200: gfh_maui_info 126 | 0x0201: gfh_maui_sec 127 | 0x0202: gfh_maui_code_key # maui_sec_key for code part 128 | 0x0203: gfh_maui_secure_ro_key # maui_sec_key for secure ro part 129 | 0x0204: gfh_maui_resource_key # maui_sec_key for resource part 130 | 0x0205: gfh_secure_ro_info 131 | 0x0206: gfh_dl_package_info 132 | 0x0207: gfh_flash_info 133 | 0x0208: gfh_macr_info 134 | 0x0209: gfh_arm_bl_info 135 | 0x020a: gfh_emmc_booting_info 136 | 0x020b: gfh_fota_info 137 | 0x020c: gfh_cbr_record_info 138 | 0x020d: gfh_confidential_bin_info 139 | 0x020e: gfh_cbr_info 140 | 0x020f: gfh_mba_info 141 | 0x0210: gfh_binary_location 142 | 0x0300: gfh_boot_cert_ctrl_content 143 | types: 144 | magic_ver: 145 | seq: 146 | - id: magic 147 | contents: 'MMM' 148 | - id: ver 149 | size: 1 150 | gfh_file_info: 151 | seq: 152 | - id: gfh_header 153 | type: gfh_header 154 | - id: identifier 155 | type: strz 156 | size: 12 157 | encoding: ASCII 158 | - id: file_ver 159 | type: u4 160 | - id: file_type 161 | type: u2 162 | enum: gfh_file_type 163 | - id: flash_dev 164 | type: u1 165 | enum: gfh_flash_dev 166 | - id: sig_type 167 | type: u1 168 | enum: gfh_sig_type 169 | - id: load_addr 170 | type: u4 171 | - id: file_len 172 | type: u4 173 | - id: max_size 174 | type: u4 175 | - id: content_offset 176 | type: u4 177 | - id: sig_len 178 | type: u4 179 | - id: jump_offset 180 | type: u4 181 | - id: attr 182 | type: attr 183 | size: 4 184 | types: 185 | attr: 186 | doc: "Flag bits in the following order: [7:0], [15:8], [23:16], [31:24]" 187 | seq: 188 | - id: reserved0 189 | type: b5 190 | - id: file_info_attr_slt 191 | type: b1 192 | - id: file_info_attr_xip 193 | type: b1 194 | - id: file_info_attr_post_build_done 195 | type: b1 196 | - id: reserved1 197 | type: b23 198 | - id: file_info_attr_dual_image 199 | type: b1 200 | gfh_dsp_info: 201 | seq: 202 | - id: gfh_header 203 | type: gfh_header 204 | - id: product_ver 205 | type: u4 206 | - id: image_type 207 | type: u4 208 | - id: platform_id 209 | type: strz 210 | size: 16 211 | encoding: UTF-8 212 | - id: project_id 213 | type: strz 214 | size: 64 215 | encoding: UTF-8 216 | - id: build_time 217 | type: strz 218 | size: 64 219 | encoding: UTF-8 220 | - id: reserved 221 | size: 64 222 | dsp_firmware: 223 | seq: 224 | - id: header 225 | type: header 226 | - id: body 227 | size-eos: true 228 | types: 229 | header: 230 | seq: 231 | - id: header_start 232 | contents: 'HDR2BEGN' 233 | - id: unk_1 234 | type: u4 235 | - id: core_count 236 | type: u4 237 | - id: core_headers 238 | type: core_header 239 | repeat: expr 240 | repeat-expr: core_count 241 | - id: header_end 242 | contents: 'HDR2EEBD' 243 | types: 244 | core_header: 245 | seq: 246 | - id: core_idx 247 | type: u4 248 | - id: core_code_len 249 | type: u4 250 | - id: core_code_checksum 251 | type: u4 252 | - id: core_data_len 253 | type: u4 254 | - id: core_data_checksum 255 | type: u4 256 | -------------------------------------------------------------------------------- /Documents.md: -------------------------------------------------------------------------------- 1 | # Documents 2 | 3 | 4 | ## Papers and Presentations 5 | 6 | * [Efficient WiMAX Receiver Implementation on a Programmable Baseband Processor](https://www.diva-portal.org/smash/record.jsf?pid=diva2:22672) 7 | * [Design of a DVB-T Receiver For SFN on a DSP-Processor](https://www.diva-portal.org/smash/record.jsf?pid=diva2:575252) 8 | * [DSP implementation of the Cholesky factorisation](https://www.diva-portal.org/smash/record.jsf?pid=diva2:753391) 9 | * [Evaluation of instruction prefetch methods for Coresonic DSP processor](https://www.diva-portal.org/smash/record.jsf?pid=diva2:935885) 10 | * [On Generating Complex Numbers for FFT and NCO Using the CORDIC Algorithm](https://www.diva-portal.org/smash/record.jsf?pid=diva2:127535) 11 | * [Bus System for Coresonic SIMT DSP](https://www.diva-portal.org/smash/record.jsf?pid=diva2:940128) 12 | * [Multicore DSP Architecture and Programming](https://www.ida.liu.se/~TDDD56/slides/14-DSP-OlaDahl.pdf) 13 | * [System Architecture for 3GPP LTE Modem using a Programmable Baseband Processor](https://www.da.isy.liu.se/pubs/diwu/diwu-SoC2009ORG.pdf) 14 | * [Bridging Dream and Reality: Programmable Baseband Processors for Software-Defined Radio](https://www.da.isy.liu.se/pubs/dake/dake-IEEECM2009%20ORG.pdf) 15 | * [Implementation of Programmable Baseband Processors](https://www.da.isy.liu.se/pubs/dake/dake-ccic2004.pdf) 16 | * [An 11 mm^2, 70 mW Fully Programmable Baseband Processor for Mobile WiMAX and DVB-T/H in 0.12 um CMOS](https://web.archive.org/web/20120425072150/http://www.coresonic.com:80/Coresonic_IEEE_JSSC_Jan09.pdf) 17 | * [Bridging Dream and Reality: Programmable Baseband Processors for Software-Defined Radio](https://web.archive.org/web/20120511140351/http://editme.bits2life.com/system/editme/4/Coresonic_IEEE_Sept09.pdf) 18 | * [MediaDSP: An Application Specific Heterogeneous Multiprocessor SoC](https://www.da.isy.liu.se/pubs/diwu/diwu-ssocc2006.pdf) 19 | 20 | 21 | ## Patents 22 | 23 | * [EP2751670B1: Digital signal processor](https://patents.google.com/patent/EP2751670B1/en) 24 | * [EP2751671B1: Digital signal processor and baseband communication device](https://patents.google.com/patent/EP2751671B1/en) 25 | * [US20060271764A1: Programmable digital signal processor including a clustered SIMD microarchitecture configured to execute complex vector instructions](https://patents.google.com/patent/US20060271764A1/en) 26 | * [US20060271765A1: Digital signal processor including a programmable network](https://patents.google.com/patent/US20060271765A1/en) 27 | * [US20070198815A1: Programmable digital signal processor having a clustered SIMD microarchitecture including a complex short multiplier and an independent vector load unit](https://patents.google.com/patent/US20070198815A1/en) 28 | * [US20140244970A1: Digital signal processor and baseband communication device](https://patents.google.com/patent/US20140244970A1/en) 29 | * [US20140281373A1: Digital signal processor and baseband communication device](https://patents.google.com/patent/US20140281373A1/en) 30 | * [US20140344549A1: Digital signal processor and baseband communication device](https://patents.google.com/patent/US20140344549A1/en) 31 | * [US20140351555A1: Digital signal processor and method for addressing a memory in a digital signal processor](https://patents.google.com/patent/US20140351555A1/en) 32 | * [US20140359252A1: Digital signal processor](https://patents.google.com/patent/US20140359252A1/en) 33 | * [US20140372728A1: Vector execution unit for digital signal processor](https://patents.google.com/patent/US20140372728A1/en) 34 | * [US7299342B2: Complex vector executing clustered SIMD micro-architecture DSP with accelerator coupled complex ALU paths each further including short multiplier/accumulator using two's complement](https://patents.google.com/patent/US7299342B2/en) 35 | * [US7415595B2: Data processing without processor core intervention by chain of accelerators selectively coupled by programmable interconnect network and to memory](https://patents.google.com/patent/US7415595B2/en) 36 | * [US8874968B1: Method and system for testing a processor designed by a configurator](https://patents.google.com/patent/US8874968B1/en) 37 | * [US9557996B2: Digital signal processor and method for addressing a memory in a digital signal processor](https://patents.google.com/patent/US9557996B2/en) 38 | 39 | 40 | ## ARM Documents 41 | 42 | ### Cortex-R4 43 | 44 | * [ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition](https://developer.arm.com/products/architecture/r-profile/docs/ddi0406/latest/arm-architecture-reference-manual-armv7-a-and-armv7-r-edition) 45 | * [Cortex-R4 and Cortex-R4F Technical Reference Manual](https://developer.arm.com/docs/ddi0363/latest/preface) 46 | 47 | ### Debug 48 | 49 | * [ARM® CoreSight™ Architecture Specification v3.0](https://static.docs.arm.com/ihi0029/e/coresight_v3_0_architecture_specification_IHI0029E.pdf) 50 | * [ARM® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2](https://static.docs.arm.com/ihi0031/d/debug_interface_v5_2_architecture_specification_IHI0031D.pdf) 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MediaTek LTE Baseband RE 2 | 3 | ## Introduction 4 | 5 | MediaTek is a fabless semiconductor company that makes, among other 6 | things, smartphone SoCs with built-in LTE modems. These SoCs interest me 7 | for the following reasons: 8 | 9 | - They're cheap. 10 | - They're extremely popular. 11 | - They're used in many inexpensive LTE smartphones. 12 | - They primarily use off-the-shelf IP cores, which for the ARM cores means 13 | documentation is publicly available. 14 | - Their Linux kernel sources are generally available, though not always 15 | buildable. 16 | - While the BSPs for these SoCs usually support code signing/image 17 | verification/etc., most phones based on them either don't enable it or 18 | implement it incorrectly, enabling us to run our own code and build our 19 | own firmware. 20 | - You can usually find their datasheets, TRMs, register manuals, 21 | functional specifications, and reference designs leaked online. 22 | - Everyone else is interested in Qualcomm SoCs, so MediaTek SoCs are 23 | currently low-hanging fruit. :) 24 | 25 | The LTE modem in these SoCs consists of two main components: 26 | 27 | - A Cortex-R4 to handle the LTE protocol. 28 | - A Coresonic DSP to hande the data-to-RF conversion. 29 | 30 | The initial goals of this project are to reverse engineer the Coresonic 31 | DSP, its "SIMT" instruction set, the interface between the Cortex-R4 and 32 | the Coresonic DSP, and the interface between the Cortex-R4 and the SoC's 33 | applications processor. Doing this will empower users to build custom 34 | modems using inexpensive, off-the-shelf Android smartphones. Some examples 35 | of what would be possible: 36 | 37 | - Over-engineered walkie-talkie. 38 | - Smartphone DECT handset. 39 | - Cognitive radio in TV whitespace. 40 | - Dongle-free smartphone digital TV receiver. 41 | - Dongle-free smartphone SDR/spectrum analyzer. 42 | - Free Software LTE modem. 43 | 44 | This repository will track the notes I write and the tools I build to 45 | do all of this. 46 | 47 | ## Current Progress 48 | 49 | The DSP firmware can be decoded. See the [DSP](DSP) directory for some 50 | scripts to do this and to read the notes on my findings. 51 | 52 | My current task list is in [Tasks.md](Tasks.md). 53 | 54 | ## Additional Information 55 | 56 | See the [General-Notes.adoc](General-Notes.adoc) file in this directory 57 | for general information about MediaTek's LTE modems and SoCs. 58 | Information on each subsystem can be found in the "Notes.md" file in the 59 | directory for that subsystem. 60 | 61 | The [Documents.md](Documents.md) file contains a list of research papers, 62 | presentations, patents, and other documents that are or might be relevant 63 | to this project. 64 | 65 | ## Chat 66 | 67 | Join us in the `#postmarketos-lowlevel` channel on 68 | [Matrix](https://matrix.to/#/#lowlevel:postmarketos.org) or 69 | [OFTC IRC](https://webchat.oftc.net/?channels=postmarketos-lowlevel) 70 | to discuss this and other low-level smartphone firmware projects. 71 | 72 | 73 | ## License 74 | 75 | Except where otherwise stated: 76 | 77 | * All software in this repository (e.g., the serial monitor and the scripts 78 | and tools to build it, tools for unpacking and generating firmware, tools 79 | for building documentation, etc.) is made available under the 80 | [GNU General Public License, version 3 or later][gpl]. 81 | * All copyrightable content that is not software (e.g., chip register and 82 | programming manuals, reverse engineering notes, this README file, etc.) is 83 | licensed under the 84 | [Creative Commons Attribution-ShareAlike 4.0 International License][cc-by-sa]. 85 | 86 | 87 | [gpl]: COPYING.txt 88 | [cc-by-sa]: https://creativecommons.org/licenses/by-sa/4.0/ 89 | -------------------------------------------------------------------------------- /SoC/MT6735/Notes.md: -------------------------------------------------------------------------------- 1 | # MT6735 Notes 2 | 3 | Just some random notes for the MT6735 SoC. 4 | 5 | - CoreSight JTAG-AP: Only the 0th and 1st scan chains are connected. 6 | 7 | - AP memory (Functional Spec page 109): 8 | - 0x00000000-0x0000ffff: 64 kB boot ROM 9 | - 0x00100000-0x0010ffff: 64 kB SRAM 10 | - 0x00200000-0x0023ffff: 256 kB L2 share SRAM 11 | - Boot ROM and SRAM access from Linux are disabled during Preloader 12 | execution. 13 | 14 | - AP<-\>BP memory mappings: 15 | - 0x10000000 (AP) <-> 0xA0000000 (BP): `infracfg_ao_reg` base address 16 | - This enables the BP core to access clock controls, GPIOs and other 17 | peripherals directly. 18 | -------------------------------------------------------------------------------- /SoC/MT6735/README.md: -------------------------------------------------------------------------------- 1 | # MT6735 2 | 3 | Primary target: [BLU R1 HD][r1hd] 4 | 5 | **NOTE**: Don't buy this phone to develop on--the device as it's being 6 | sold today has been been locked down by Amazon/BLU and (to my knowledge) 7 | can no longer enter preloader download mode. If you want a device to 8 | hack on, the [Orange Pi 4G-IoT][orangepi] is a far more open 9 | alternative, and I'll be porting the scripts in this directory to work 10 | on that device going forward. Check out the 11 | [MT6737M directory](../MT6737M) for more information and scripts for 12 | that device. 13 | 14 | Notes on this SoC can be found in [Notes.md](Notes.md). 15 | 16 | 17 | [r1hd]: https://bluproducts.com/r1-hd/ 18 | [orangepi]: http://www.orangepi.org/Orange%20Pi%204G-IOT/ 19 | -------------------------------------------------------------------------------- /SoC/MT6735/boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | adb wait-for-device 22 | adb reboot bootloader 23 | 24 | fastboot boot ./bootimg/boot_new.img 25 | 26 | adb wait-for-device 27 | sleep 30 28 | adb shell "su -c setenforce permissive" 29 | adb shell getenforce 30 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/.gitignore: -------------------------------------------------------------------------------- 1 | boot_new.img 2 | mkbootimg 3 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/README.md: -------------------------------------------------------------------------------- 1 | # boot.img 2 | 3 | ## Building 4 | 5 | 1. Build the kernel using the instructions in the `../kernel` directory. 6 | 2. Extract the `boot.img` from the `boot` partition of your android 7 | device and place it in the `./dump` directory. 8 | 3. Run `./build.sh` in this `bootimg` directory. 9 | 4. Boot your device from the newly-generated `boot_new.img` file. 10 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | # https://stackoverflow.com/a/4774063 22 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 23 | MKBOOTIMG_PATH=$SCRIPTPATH/mkbootimg 24 | KERNEL=$SCRIPTPATH/../kernel/android_kernel_mediatek_mt6735/arch/arm/boot/zImage-dtb 25 | DUMP_PATH=$SCRIPTPATH/dump 26 | OLD_BOOTIMG=$DUMP_PATH/boot.img 27 | OLD_RAMDISK=$DUMP_PATH/boot.img-ramdisk.gz 28 | NEW_BOOTIMG=$SCRIPTPATH/boot_new.img 29 | NEW_RAMDISK_PATH=$SCRIPTPATH/ramdisk 30 | NEW_RAMDISK=$NEW_RAMDISK_PATH/ramdisk-no-mdinit.gz 31 | 32 | if [ ! -d $MKBOOTIMG_PATH ]; then 33 | git clone https://github.com/Ud3v0id/mkbootimg.git $MKBOOTIMG_PATH 34 | make -C $MKBOOTIMG_PATH 35 | fi 36 | 37 | if [ ! -e $OLD_RAMDISK ]; then 38 | if [ ! -e $OLD_BOOTIMG ]; then 39 | echo "Error: Could not find $OLD_BOOTIMG" 40 | exit 1 41 | fi 42 | $MKBOOTIMG_PATH/unpackbootimg -i $OLD_BOOTIMG -o $DUMP_PATH 43 | fi 44 | 45 | if [ ! -e $NEW_RAMDISK ]; then 46 | (cd $NEW_RAMDISK_PATH && ./build.sh) 47 | fi 48 | 49 | $MKBOOTIMG_PATH/mkbootimg \ 50 | --kernel $KERNEL \ 51 | --ramdisk $NEW_RAMDISK \ 52 | --cmdline bootopt=64S3,32N2,32N2 \ 53 | --board BLU_R0011UU_V12 \ 54 | --base 40000000 \ 55 | --pagesize 2048 \ 56 | --ramdisk_offset 04000000 \ 57 | --tags_offset 0e000000 \ 58 | -o $NEW_BOOTIMG 59 | 60 | echo "Boot image generated at $NEW_BOOTIMG" 61 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/dump/.gitignore: -------------------------------------------------------------------------------- 1 | boot.img 2 | boot.img-* 3 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/dump/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Place the `boot.img` file dumped from your device in this directory. 4 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/ramdisk/.gitignore: -------------------------------------------------------------------------------- 1 | ramdisk* 2 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/ramdisk/0001-disable-modem-init.patch: -------------------------------------------------------------------------------- 1 | diff -ur ./ramdisk/init.modem.rc ./ramdisk/init.modem.rc 2 | --- ./ramdisk/init.modem.rc 2018-06-05 19:55:56.539577904 -0500 3 | +++ ./ramdisk/init.modem.rc 2018-06-05 20:08:17.514378702 -0500 4 | @@ -112,11 +112,11 @@ 5 | class core 6 | oneshot 7 | 8 | -service ccci_mdinit /system/bin/ccci_mdinit 0 9 | - user system 10 | - group radio system 11 | - class core 12 | - oneshot 13 | +#service ccci_mdinit /system/bin/ccci_mdinit 0 14 | +# user system 15 | +# group radio system 16 | +# class core 17 | +# oneshot 18 | 19 | service ccci_rpcd /system/bin/ccci_rpcd 0 20 | user radio 21 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/ramdisk/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | # https://stackoverflow.com/a/4774063 22 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 23 | OLD_RD=$SCRIPTPATH/../dump/*-ramdisk.gz 24 | 25 | if [ ! -d ramdisk ]; then 26 | mkdir ramdisk 27 | 28 | # Generate a list of all the files in the ramdisk. 29 | zcat $OLD_RD | cpio -t > ramdisk.list 30 | 31 | # Extract the ramdisk without root. 32 | # https://unix.stackexchange.com/a/289280 33 | zcat $OLD_RD | fakeroot -s ramdisk.fakeroot -- cpio -i -D ramdisk 34 | fi 35 | 36 | # Patch files. 37 | fakeroot -i ramdisk.fakeroot -- patch -p1 < 0001-disable-modem-init.patch 38 | 39 | # Generate new ramdisk. 40 | fakeroot -i ramdisk.fakeroot -- cpio -o -H newc -D ramdisk < ramdisk.list | gzip > ramdisk-no-mdinit.gz 41 | -------------------------------------------------------------------------------- /SoC/MT6735/bootimg/ramdisk/rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | # Generate new ramdisk. 22 | fakeroot -i ramdisk.fakeroot -- cpio -o -H newc -D ramdisk < ramdisk.list | gzip > ramdisk-no-mdinit.gz 23 | -------------------------------------------------------------------------------- /SoC/MT6735/dump-to-bin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | '''\ 20 | A simple utility to convert register dumps to binary data. 21 | 22 | For example: 23 | 24 | ./dump.sh 10200000 1000 | ./dump-to-bin.py | hexdump -C 25 | 26 | You can also read files directly: 27 | 28 | ./dump-to-bin.py dump.txt | hexdump -C 29 | 30 | ''' 31 | 32 | import fileinput 33 | import struct 34 | import sys 35 | 36 | if __name__ == "__main__": 37 | for line in fileinput.input(): 38 | data = int(line.rstrip('\n').split(' = ')[1], 16) 39 | sys.stdout.buffer.write(struct.pack(' 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su -c /data/local/tmp/dump $@ 20 | -------------------------------------------------------------------------------- /SoC/MT6735/dump/.gitignore: -------------------------------------------------------------------------------- 1 | dump 2 | -------------------------------------------------------------------------------- /SoC/MT6735/dump/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2018 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | CC := arm-linux-gnueabihf-gcc 19 | CFLAGS := -Wall -Werror -static 20 | 21 | all: dump 22 | 23 | %: %.c 24 | $(CC) $(CFLAGS) -o $@ $< 25 | 26 | push: dump 27 | adb push $^ /data/local/tmp 28 | 29 | clean: 30 | rm -f dump 31 | 32 | .PHONY: all clean push 33 | -------------------------------------------------------------------------------- /SoC/MT6735/dump/dump.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2018, 2020 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | 29 | int main(int argc, char *argv[]) 30 | { 31 | int fd; 32 | void *map; 33 | volatile uint32_t *regs; 34 | 35 | uint32_t address; 36 | uint32_t reg_base; 37 | uint32_t reg_offset; 38 | uint32_t length; 39 | uint32_t pages; 40 | 41 | if (argc != 3) { 42 | fprintf(stderr, "Usage: %s address length\n", argv[0]); 43 | return -1; 44 | } 45 | 46 | if (sscanf(argv[1], "%x", &address) != 1) { 47 | fprintf(stderr, "Error: address \"%s\" is not an integer\n", argv[1]); 48 | return -1; 49 | } 50 | 51 | if (address % 4 != 0) { 52 | fprintf(stderr, "Error: address 0x%08x must be a multiple of 4\n", address); 53 | return -1; 54 | } 55 | 56 | if (sscanf(argv[2], "%x", &length) != 1) { 57 | fprintf(stderr, "Error: length \"%s\" is not an integer\n", argv[2]); 58 | return -1; 59 | } 60 | 61 | if (length % 4 != 0) { 62 | fprintf(stderr, "Error: length 0x%08x must be a multiple of 4\n", length); 63 | return -1; 64 | } 65 | 66 | size_t page_size = sysconf(_SC_PAGESIZE); 67 | reg_offset = address % page_size; 68 | reg_base = address - reg_offset; 69 | pages = ((reg_offset + length + (page_size - 1)) / page_size); 70 | //fprintf(stderr, "reg_offset = 0x%08x, reg_base = 0x%08x, pages = %d\n", reg_offset, reg_base, pages); 71 | 72 | if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 73 | perror("can't open /dev/mem"); 74 | return -1; 75 | } 76 | 77 | map = mmap( 78 | NULL, 79 | page_size * pages, 80 | PROT_READ|PROT_WRITE, 81 | MAP_SHARED, 82 | fd, 83 | reg_base 84 | ); 85 | if (map == (void *)(-1)) { 86 | perror("mmap failed"); 87 | return -1; 88 | } 89 | 90 | regs = (volatile uint32_t *)map; 91 | 92 | for (uint32_t i = 0; i < length; i += 4) { 93 | printf("*0x%08x = 0x%08x\n", address+i, regs[(reg_offset+i)/4]); 94 | } 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /SoC/MT6735/dump_md_debug_registers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su echo echo 6 \\\> /sys/kernel/ccci/debug 20 | adb shell su echo echo register \\\> /sys/kernel/ccci/mdsys1/dump 21 | adb shell dmesg | grep sush | grep ccci 22 | -------------------------------------------------------------------------------- /SoC/MT6735/dump_md_smem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su echo echo 6 \\\> /sys/kernel/ccci/debug 20 | adb shell su echo echo smem \\\> /sys/kernel/ccci/mdsys1/dump 21 | adb shell dmesg | grep sush | grep ccci 22 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/.gitignore: -------------------------------------------------------------------------------- 1 | android_kernel_mediatek_mt6735 2 | arm-eabi-4.8 3 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/0002-enable-ccci-debug.patch: -------------------------------------------------------------------------------- 1 | diff --git a/drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c b/drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c 2 | index 9e006fd9..743ebe62 100755 3 | --- a/drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c 4 | +++ b/drivers/misc/mediatek/ccci_util/ccci_util_lib_load_img.c 5 | @@ -1,3 +1,5 @@ 6 | +#define DEBUG 7 | + 8 | #include 9 | #include 10 | #include 11 | diff --git a/drivers/misc/mediatek/ccci_util/ccci_util_log.h b/drivers/misc/mediatek/ccci_util/ccci_util_log.h 12 | index 7e0b8281..ff434d45 100644 13 | --- a/drivers/misc/mediatek/ccci_util/ccci_util_log.h 14 | +++ b/drivers/misc/mediatek/ccci_util/ccci_util_log.h 15 | @@ -3,20 +3,20 @@ 16 | 17 | /* No MD id message part */ 18 | #define CCCI_UTIL_DBG_MSG(fmt, args...)\ 19 | -do {} while (0)/* pr_debug("[ccci0/util]" fmt, ##args) */ 20 | + pr_debug("[ccci0/util]" fmt, ##args) 21 | 22 | #define CCCI_UTIL_INF_MSG(fmt, args...)\ 23 | -do {} while (0)/* pr_debug("[ccci0/util]" fmt, ##args) */ 24 | + pr_debug("[ccci0/util]" fmt, ##args) 25 | 26 | #define CCCI_UTIL_ERR_MSG(fmt, args...)\ 27 | pr_err("[ccci0/util]" fmt, ##args) 28 | 29 | /* With MD id message part */ 30 | #define CCCI_UTIL_DBG_MSG_WITH_ID(id, fmt, args...)\ 31 | -do {} while (0)/* pr_debug("[ccci%d/util]" fmt, (id+1), ##args) */ 32 | + pr_debug("[ccci%d/util]" fmt, (id+1), ##args) 33 | 34 | #define CCCI_UTIL_INF_MSG_WITH_ID(id, fmt, args...)\ 35 | -do {} while (0)/* pr_debug("[ccci%d/util]" fmt, (id+1), ##args) */ 36 | + pr_debug("[ccci%d/util]" fmt, (id+1), ##args) 37 | 38 | #define CCCI_UTIL_NOTICE_MSG_WITH_ID(id, fmt, args...) \ 39 | pr_notice("[ccci%d/util]" fmt, (id+1), ##args) 40 | diff --git a/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c b/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 41 | index f7d28150..3c113bce 100644 42 | --- a/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 43 | +++ b/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 44 | @@ -1,3 +1,5 @@ 45 | +#define DEBUG 46 | + 47 | #include 48 | #include 49 | #include 50 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/0003-disable-dsp-memory-region-protection.patch: -------------------------------------------------------------------------------- 1 | diff --git a/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c b/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 2 | index f7d28150..3c113bce 100644 3 | --- a/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 4 | +++ b/drivers/misc/mediatek/eccci/mt6735/ccci_platform.c 5 | @@ -255,9 +255,9 @@ void ccci_set_dsp_region_protection(struct ccci_modem *md, int loaded) 6 | dsp_mem_phy_start = (unsigned int)md->mem_layout.dsp_region_phy; 7 | dsp_mem_phy_end = ((dsp_mem_phy_start + md->mem_layout.dsp_region_size + 0xFFFF) & (~0xFFFF)) - 0x1; 8 | 9 | - CCCI_INF_MSG(md->index, TAG, "MPU Start protect DSP region<%d:%08x:%08x> %x\n", 10 | + CCCI_INF_MSG(md->index, TAG, "MPU Start protect DSP region<%d:%08x:%08x> %x (jk lol)\n", 11 | dsp_mem_mpu_id, dsp_mem_phy_start, dsp_mem_phy_end, dsp_mem_mpu_attr); 12 | - emi_mpu_set_region_protection(dsp_mem_phy_start, dsp_mem_phy_end, dsp_mem_mpu_id, dsp_mem_mpu_attr); 13 | + //emi_mpu_set_region_protection(dsp_mem_phy_start, dsp_mem_phy_end, dsp_mem_mpu_id, dsp_mem_mpu_attr); 14 | #else 15 | if (!loaded) { 16 | dsp_mem_phy_start = (unsigned int)md->mem_layout.dsp_region_phy; 17 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/0004-enable-wmt-debug.patch: -------------------------------------------------------------------------------- 1 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile 2 | index 644fc383..828f9cf8 100644 3 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile 4 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile 5 | @@ -18,6 +18,8 @@ ifeq ($(CONFIG_ARCH_MT6580), y) 6 | subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 7 | endif 8 | 9 | +subdir-ccflags-y += -DDEBUG 10 | + 11 | ifeq ($(CONFIG_MTK_COMBO), m) 12 | # WMT DRIVER 13 | obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o 14 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile 15 | index 9df71b9e..ca6d27ab 100644 16 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile 17 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile 18 | @@ -8,6 +8,8 @@ ccflags-y += \ 19 | -I$(src)/../../common_detect \ 20 | -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ 21 | 22 | +ccflags-y += -DDEBUG 23 | + 24 | obj-y += wmt_core.o \ 25 | wmt_ctrl.o \ 26 | wmt_func.o \ 27 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c 28 | index 9549cd8c..27109885 100644 29 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c 30 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c 31 | @@ -68,7 +68,7 @@ 32 | 33 | #define CFG_SUBSYS_COEX_NEED 0 34 | 35 | -#define CFG_WMT_COREDUMP_ENABLE 0 36 | +#define CFG_WMT_COREDUMP_ENABLE 1 37 | 38 | #define CFG_WMT_MULTI_PATCH (1) 39 | 40 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile 41 | index ff0f0b0a..5c5fa5e4 100644 42 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile 43 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile 44 | @@ -10,7 +10,7 @@ ccflags-y += \ 45 | -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ 46 | -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach 47 | 48 | -ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 49 | +ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -DDEBUG 50 | 51 | obj-y += stp_btif.o \ 52 | stp_dbg.o \ 53 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c 54 | index 70f6b361..c71de766 100644 55 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c 56 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c 57 | @@ -506,7 +506,7 @@ INT32 wcn_core_dump_timeout(void) 58 | return 0; 59 | } 60 | 61 | -#define ENABLE_F_TRACE 0 62 | +#define ENABLE_F_TRACE 1 63 | /* wcn_core_dump_flush - Fulsh dump data and reset core dump sys 64 | * 65 | * Retunr 0 if success, else error code 66 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile 67 | index 15792bab..60ac8a0f 100644 68 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile 69 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile 70 | @@ -9,7 +9,7 @@ ccflags-y += \ 71 | -I$(src)/../../../common_detect \ 72 | -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach 73 | 74 | -ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 75 | +ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -DDEBUG 76 | 77 | ifeq ($(CONFIG_MTK_TC1_FEATURE), y) 78 | ccflags-y += -DCFG_TC1_FEATURE=1 79 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt6735/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt6735/Makefile 80 | index b28da785..00e478ed 100644 81 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/mt6735/Makefile 82 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt6735/Makefile 83 | @@ -8,6 +8,7 @@ ccflags-y += \ 84 | 85 | ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM) 86 | ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach 87 | +ccflags-y += -DDEBUG 88 | 89 | subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT 90 | 91 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/0005-fix-wmt_dev_dbg_write.patch: -------------------------------------------------------------------------------- 1 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h 2 | index 52b782c6..34838081 100644 3 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h 4 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h 5 | @@ -233,6 +233,7 @@ extern char *osal_strncat(char *dst, const char *src, UINT32 len); 6 | extern char *osal_strchr(const char *str, UINT8 c); 7 | extern char *osal_strsep(char **str, const char *c); 8 | extern int osal_strtol(const char *str, UINT32 adecimal, long *res); 9 | +extern int osal_strtoul(const char *str, UINT32 adecimal, unsigned long *res); 10 | extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); 11 | extern char *osal_strstr(char *str1, const char *str2); 12 | 13 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c 14 | index 5ea848f8..ab7eeb3e 100644 15 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c 16 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c 17 | @@ -1210,7 +1210,7 @@ static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, s 18 | INT32 x = 0, y = 0, z = 0; 19 | PINT8 pToken = NULL; 20 | PINT8 pDelimiter = " \t"; 21 | - long res; 22 | + unsigned long res; 23 | INT32 ret; 24 | 25 | WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); 26 | @@ -1230,24 +1230,24 @@ static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, s 27 | pToken = osal_strsep(&pBuf, pDelimiter); 28 | 29 | if (pToken != NULL) { 30 | - ret = osal_strtol(pToken, 16, &res); 31 | + ret = osal_strtoul(pToken, 16, &res); 32 | if (ret) { 33 | WMT_ERR_FUNC("get x fail(%d)\n", ret); 34 | x = 0; 35 | } 36 | - x = res; 37 | + x = (INT32)res; 38 | } else { 39 | x = 0; 40 | } 41 | 42 | pToken = osal_strsep(&pBuf, "\t\n "); 43 | if (pToken != NULL) { 44 | - ret = osal_strtol(pToken, 16, &res); 45 | + ret = osal_strtoul(pToken, 16, &res); 46 | if (ret) { 47 | WMT_ERR_FUNC("get y fail(%d)\n", ret); 48 | y = 0; 49 | } 50 | - y = res; 51 | + y = (INT32)res; 52 | WMT_INFO_FUNC("y = 0x%08x\n\r", y); 53 | } else { 54 | y = 3000; 55 | @@ -1259,12 +1259,12 @@ static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, s 56 | 57 | pToken = osal_strsep(&pBuf, "\t\n "); 58 | if (pToken != NULL) { 59 | - ret = osal_strtol(pToken, 16, &res); 60 | + ret = osal_strtoul(pToken, 16, &res); 61 | if (ret) { 62 | WMT_ERR_FUNC("get z fail(%d)\n", ret); 63 | z = 0; 64 | } 65 | - z = res; 66 | + z = (INT32)res; 67 | } else { 68 | z = 10; 69 | /*efuse, register read write default value */ 70 | diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c 71 | index 2f0adfbb..dec11b62 100644 72 | --- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c 73 | +++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c 74 | @@ -152,6 +152,11 @@ _osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) 75 | return kstrtol(str, adecimal, res); 76 | } 77 | 78 | +_osal_inline_ int osal_strtoul(const char *str, UINT32 adecimal, unsigned long *res) 79 | +{ 80 | + return kstrtoul(str, adecimal, res); 81 | +} 82 | + 83 | _osal_inline_ char *osal_strstr(char *str1, const char *str2) 84 | { 85 | return strstr(str1, str2); 86 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/0006-config.patch: -------------------------------------------------------------------------------- 1 | --- arch/arm/configs/p6601_defconfig 2017-12-17 17:38:02.740316646 -0600 2 | +++ .config 2018-01-25 15:39:54.221676711 -0600 3 | @@ -108,7 +108,7 @@ 4 | # CONFIG_RCU_NOCB_CPU is not set 5 | # CONFIG_BUILD_BIN2C is not set 6 | # CONFIG_IKCONFIG is not set 7 | -CONFIG_LOG_BUF_SHIFT=18 8 | +CONFIG_LOG_BUF_SHIFT=21 9 | CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 10 | CONFIG_GENERIC_SCHED_CLOCK=y 11 | CONFIG_CGROUPS=y 12 | @@ -206,10 +206,10 @@ 13 | CONFIG_HAVE_ARCH_SECCOMP_FILTER=y 14 | CONFIG_SECCOMP_FILTER=y 15 | CONFIG_HAVE_CC_STACKPROTECTOR=y 16 | -CONFIG_CC_STACKPROTECTOR=y 17 | -# CONFIG_CC_STACKPROTECTOR_NONE is not set 18 | +# CONFIG_CC_STACKPROTECTOR is not set 19 | +CONFIG_CC_STACKPROTECTOR_NONE=y 20 | # CONFIG_CC_STACKPROTECTOR_REGULAR is not set 21 | -CONFIG_CC_STACKPROTECTOR_STRONG=y 22 | +# CONFIG_CC_STACKPROTECTOR_STRONG is not set 23 | CONFIG_HAVE_CONTEXT_TRACKING=y 24 | CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y 25 | CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y 26 | @@ -1959,7 +1959,7 @@ 27 | # CONFIG_SERIAL_NONSTANDARD is not set 28 | # CONFIG_N_GSM is not set 29 | # CONFIG_TRACE_SINK is not set 30 | -# CONFIG_DEVMEM is not set 31 | +CONFIG_DEVMEM=y 32 | # CONFIG_DEVKMEM is not set 33 | 34 | # 35 | @@ -2111,7 +2111,7 @@ 36 | CONFIG_GPIO_DEVRES=y 37 | CONFIG_OF_GPIO=y 38 | # CONFIG_DEBUG_GPIO is not set 39 | -# CONFIG_GPIO_SYSFS is not set 40 | +CONFIG_GPIO_SYSFS=y 41 | 42 | # 43 | # Memory mapped GPIO drivers: 44 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/README.md: -------------------------------------------------------------------------------- 1 | # kernel 2 | 3 | ## Building 4 | 5 | 1. Run `./build.sh` to download the toolchain and kernel sources, patch 6 | the kernel sources, generate and patch the kernel config, and build 7 | the kernel. 8 | - If you've already applied patches, use the `./rebuild.sh` script instead. 9 | 2. Your new kernel will be placed in 10 | `./android_kernel_mediatek_mt6735/arch/arm/boot/zImage-dtb`. 11 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018-2019 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | # https://stackoverflow.com/a/4774063 22 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 23 | TOOLPATH=$SCRIPTPATH/arm-eabi-4.8 24 | KERNELPATH=$SCRIPTPATH/android_kernel_mediatek_mt6735 25 | 26 | [ -d $TOOLPATH ] || git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8 $TOOLPATH 27 | [ -d $KERNELPATH ] || git clone https://github.com/blumonks/android_kernel_mediatek_mt6735.git $KERNELPATH 28 | 29 | export CROSS_COMPILE="$TOOLPATH/bin/arm-eabi-" 30 | export ARCH=arm 31 | export ARCH_MTK_PLATFORM=mt6735 32 | 33 | cd $KERNELPATH 34 | 35 | for i in {0001..0005}; do 36 | patch -p1 < ../$i*.patch 37 | done 38 | 39 | make p6601_defconfig 40 | 41 | patch .config ../0006-config.patch 42 | 43 | make -j4 44 | -------------------------------------------------------------------------------- /SoC/MT6735/kernel/rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | # https://stackoverflow.com/a/4774063 22 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 23 | TOOLPATH=$SCRIPTPATH/arm-eabi-4.8 24 | KERNELPATH=$SCRIPTPATH/android_kernel_mediatek_mt6735 25 | 26 | export CROSS_COMPILE="$TOOLPATH/bin/arm-eabi-" 27 | export ARCH=arm 28 | export ARCH_MTK_PLATFORM=mt6735 29 | 30 | cd $KERNELPATH 31 | 32 | make -j4 33 | -------------------------------------------------------------------------------- /SoC/MT6735/md_dump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2019 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su -c /data/local/tmp/md_dump $@ 20 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2019 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su -c /data/local/tmp/md_poke $@ 20 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | md_dump 3 | md_poke 4 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | # Copyright (C) 2019 Forest Crossman 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | 19 | CC := arm-linux-gnueabihf-gcc 20 | CFLAGS := -Wall -Werror -static 21 | 22 | all: md_dump md_poke 23 | 24 | md_dump: md_dump.o common.o 25 | $(CC) $(CFLAGS) -o $@ $^ 26 | 27 | md_poke: md_poke.o common.o 28 | $(CC) $(CFLAGS) -o $@ $^ 29 | 30 | %.o: %.c 31 | $(CC) $(CFLAGS) -c -o $@ $< 32 | 33 | push: md_dump md_poke 34 | adb push $^ /data/local/tmp 35 | 36 | clean: 37 | rm -f md_dump md_poke *.o 38 | 39 | .PHONY: all clean push 40 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/common.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "common.h" 30 | 31 | // These are just GPIO registers I'm using as generic un-cached memory. 32 | #define AP2MD_REG 0x10211160 33 | #define MD2AP_REG 0x10211150 34 | 35 | static void send_chr(mem_info_t * mem_info, char c) { 36 | volatile uint32_t * regs = mem_info->regs; 37 | uint32_t ap2md_offset = mem_info->ap2md_offset; 38 | 39 | printf("send_chr(0x%02X): Wait for TX buffer to become ready...\n", c); 40 | // Wait for the MD to clear the "data valid" flag. 41 | while ((regs[ap2md_offset/4] & 0x100) != 0); 42 | printf("send_chr(0x%02X): Sending...\n", c); 43 | 44 | regs[ap2md_offset/4] &= 0xffffff00; 45 | regs[ap2md_offset/4] |= c; 46 | regs[ap2md_offset/4] |= 0x100; 47 | printf("send_chr(0x%02X): Sent!\n", c); 48 | } 49 | 50 | static char recv_chr(mem_info_t * mem_info) { 51 | volatile uint32_t * regs = mem_info->regs; 52 | uint32_t md2ap_offset = mem_info->md2ap_offset; 53 | char ret; 54 | 55 | printf("recv_chr(): Waiting for data in RX buffer...\n"); 56 | // Wait for the MD to set the "data valid" flag. 57 | while ((regs[md2ap_offset/4] & 0x100) == 0); 58 | printf("recv_chr(): Reading data...\n"); 59 | 60 | ret = regs[md2ap_offset/4] & 0xff; 61 | regs[md2ap_offset/4] &= 0xfffffeff; 62 | printf("recv_chr(): Read 0x%02X.\n", ret); 63 | 64 | return ret; 65 | } 66 | 67 | void mem_write(mem_info_t * mem_info, uint32_t addr, uint32_t data) { 68 | const uint32_t pkt_len = 9; 69 | const char buf[] = { 70 | CMD_WRITE, 71 | addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, (addr >> 24) & 0xff, 72 | data & 0xff, (data >> 8) & 0xff, (data >> 16) & 0xff, (data >> 24) & 0xff, 73 | }; 74 | printf("mem_write(0x%08X, 0x%08X): Sending packet: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", 75 | addr, data, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); 76 | for (uint32_t i = 0; i < pkt_len; i++) { 77 | send_chr(mem_info, buf[i]); 78 | } 79 | printf("mem_write(0x%08X, 0x%08X): Done.\n", addr, data); 80 | } 81 | 82 | uint32_t mem_read(mem_info_t * mem_info, uint32_t addr) { 83 | uint32_t ret = 0; 84 | const uint32_t pkt_len = 5; 85 | char buf[] = { CMD_READ, addr & 0xff, (addr >> 8) & 0xff, (addr >> 16) & 0xff, (addr >> 24) & 0xff }; 86 | printf("mem_read(0x%08X): Sending packet: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", 87 | addr, buf[0], buf[1], buf[2], buf[3], buf[4]); 88 | for (uint32_t i = 0; i < pkt_len; i++) { 89 | send_chr(mem_info, buf[i]); 90 | } 91 | printf("mem_read(0x%08X): Receiving data...\n", addr); 92 | for (uint32_t i = 0; i < 4; i++) { 93 | ret |= recv_chr(mem_info) << (8 * i); 94 | } 95 | printf("mem_read(0x%08X): Done.\n", addr); 96 | return ret; 97 | } 98 | 99 | int get_mem_info(mem_info_t * mem_info) { 100 | int fd; 101 | void *map; 102 | volatile uint32_t *regs; 103 | 104 | uint32_t reg_base; 105 | uint32_t reg_offset; 106 | 107 | if (mem_info == NULL) { 108 | fprintf(stderr, "Error: \"mem_info\" wasn't set\n"); 109 | return -1; 110 | } 111 | 112 | long page_size = sysconf(_SC_PAGESIZE); 113 | reg_offset = MD2AP_REG % page_size; 114 | reg_base = MD2AP_REG - reg_offset; 115 | 116 | if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 117 | perror("can't open /dev/mem"); 118 | return -1; 119 | } 120 | 121 | map = mmap( 122 | NULL, 123 | page_size, 124 | PROT_READ|PROT_WRITE, 125 | MAP_SHARED, 126 | fd, 127 | reg_base 128 | ); 129 | if (map == (void *)(-1)) { 130 | perror("mmap failed"); 131 | return -1; 132 | } 133 | 134 | regs = (volatile uint32_t *)map; 135 | 136 | mem_info->regs = regs; 137 | mem_info->ap2md_offset = reg_offset + AP2MD_REG - MD2AP_REG; 138 | mem_info->md2ap_offset = reg_offset; 139 | 140 | return 0; 141 | } 142 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/common.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef COMMON_H 22 | #define COMMON_H 23 | 24 | typedef enum { 25 | CMD_READ = 0x40, 26 | CMD_WRITE = 0x80, 27 | } cmd_t; 28 | 29 | typedef struct mem_info_s { 30 | volatile uint32_t * regs; 31 | uint32_t ap2md_offset; 32 | uint32_t md2ap_offset; 33 | } mem_info_t; 34 | 35 | void mem_write(mem_info_t * mem_info, uint32_t addr, uint32_t data); 36 | 37 | uint32_t mem_read(mem_info_t * mem_info, uint32_t addr); 38 | 39 | int get_mem_info(mem_info_t * mem_info); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/md_dump.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include "common.h" 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | uint32_t address; 29 | uint32_t length; 30 | 31 | if (argc != 3) { 32 | fprintf(stderr, "Usage: %s address length\n", argv[0]); 33 | return -1; 34 | } 35 | 36 | if (sscanf(argv[1], "%x", &address) != 1) { 37 | fprintf(stderr, "Error: address \"%s\" is not an integer\n", argv[1]); 38 | return -1; 39 | } 40 | 41 | if (address % 4 != 0) { 42 | fprintf(stderr, "Error: address 0x%08x must be a multiple of 4\n", address); 43 | return -1; 44 | } 45 | 46 | if (sscanf(argv[2], "%x", &length) != 1) { 47 | fprintf(stderr, "Error: length \"%s\" is not an integer\n", argv[2]); 48 | return -1; 49 | } 50 | 51 | if (length % 4 != 0) { 52 | fprintf(stderr, "Error: length 0x%08x must be a multiple of 4\n", length); 53 | return -1; 54 | } 55 | 56 | mem_info_t mem_info; 57 | 58 | if (get_mem_info(&mem_info) != 0) { 59 | fprintf(stderr, "Error: get_mem_info() failed\n"); 60 | return -1; 61 | } 62 | 63 | for (uint32_t i = 0; i < length; i += 4) { 64 | printf("*0x%08x = 0x%08x\n", address+i, mem_read(&mem_info, address+i)); 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /SoC/MT6735/md_poke/md_poke.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include "common.h" 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | uint32_t address; 29 | uint32_t value; 30 | 31 | if (argc < 2 || argc > 3) { 32 | fprintf(stderr, "Usage: %s address [value]\n", argv[0]); 33 | return -1; 34 | } 35 | 36 | if (sscanf(argv[1], "%x", &address) != 1) { 37 | fprintf(stderr, "Error: address \"%s\" is not an integer\n", argv[1]); 38 | return -1; 39 | } 40 | 41 | if (address % 4 != 0) { 42 | fprintf(stderr, "Error: address 0x%08x must be a multiple of 4\n", address); 43 | return -1; 44 | } 45 | 46 | if (argc == 3) { 47 | if (sscanf(argv[2], "%x", &value) != 1) { 48 | fprintf(stderr, "Error: value \"%s\" is not an integer\n", argv[2]); 49 | return -1; 50 | } 51 | } 52 | 53 | mem_info_t mem_info; 54 | 55 | if (get_mem_info(&mem_info) != 0) { 56 | fprintf(stderr, "Error: get_mem_info() failed\n"); 57 | return -1; 58 | } 59 | 60 | printf("*0x%08x = 0x%08x\n", address, mem_read(&mem_info, address)); 61 | if (argc == 3) { 62 | mem_write(&mem_info, address, value); 63 | printf("*0x%08x = 0x%08x\n", address, mem_read(&mem_info, address)); 64 | } 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.img 4 | *.map 5 | *.o 6 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | # Copyright (C) 2018-2019 Forest Crossman 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | 19 | AS := arm-none-eabi-as 20 | ASFLAGS := -mcpu=cortex-r4 21 | CC := arm-none-eabi-gcc 22 | CFLAGS := -mcpu=cortex-r4 -mthumb -mfloat-abi=soft -fpie -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -Os 23 | LD := arm-none-eabi-ld 24 | LDFLAGS := -T modem.ld -Map test.map 25 | 26 | all: test.img test.bin test.elf 27 | 28 | %.o: %.c 29 | $(CC) $(CFLAGS) -c -o $@ $< 30 | 31 | %.o: %.S 32 | $(AS) $(ASFLAGS) -o $@ $< 33 | 34 | test.elf: vectors.o init.o test.o 35 | $(LD) $(LDFLAGS) -o $@ $^ 36 | 37 | %.bin: %.elf 38 | arm-none-eabi-objcopy -S -O binary $< $@ 39 | chmod -x $@ 40 | 41 | %.img: %.bin make_img.py 42 | ./make_img.py -o $@ $< 43 | 44 | install: test.img 45 | adb push $< /data/local/tmp 46 | adb shell su -c mount -o remount,rw /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system /system 47 | adb shell su -c cp /data/local/tmp/$< /system/etc/firmware/modem_1_lwg_n.img 48 | adb shell su -c chmod 644 /system/etc/firmware/modem_1_lwg_n.img 49 | adb shell su -c mount -o remount,ro /dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/system /system 50 | 51 | load: 52 | adb shell su -c /system/bin/ccci_mdinit 0 53 | 54 | dmesg: 55 | adb shell dmesg | grep ccci_mdinit 56 | 57 | disasm-bin: test.bin 58 | arm-none-eabi-objdump -marm -Mforce-thumb -b binary -D $< 59 | 60 | disasm-elf: test.elf 61 | arm-none-eabi-objdump -d $< 62 | 63 | clean: 64 | rm -f test.img test.bin *.o *.elf *.map 65 | 66 | .PHONY: all clean install load dmesg disasm-bin disasm-elf 67 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/init.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | .file "init.S" 22 | .syntax unified 23 | 24 | .globl _start 25 | 26 | .section .init, "ax" 27 | .globl _start 28 | 29 | _start: 30 | mov r0, #0 31 | mov r1, #0 32 | mov r2, #0 33 | mov r3, #0 34 | mov r4, #0 35 | mov r5, #0 36 | mov r6, #0 37 | mov r7, #0 38 | mov r8, #0 39 | mov r9, #0 40 | mov r10, #0 41 | mov r11, #0 42 | mov r12, #0 43 | mov sp, #0 44 | mov lr, #0 45 | 46 | mov sp, #0x38000000 47 | 48 | ldr pc, =main 49 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/make_img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # make_image.py - A tool for generating bootable modem images 5 | # Copyright (C) 2018, 2023 Forest Crossman 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import argparse 22 | import struct 23 | from datetime import datetime, UTC 24 | 25 | 26 | def gen_footer(data): 27 | # drivers/misc/mediatek/include/mt-plat/mt_ccci_common.h 28 | # md_check_header_v3 29 | f = b'CHECK_HEADER' # check_header 30 | f += struct.pack('rom 33 | 34 | /* C++ Static constructors/destructors, also used for __attribute__ 35 | * ((constructor)) and the likes */ 36 | .preinit_array : { 37 | . = ALIGN(4); 38 | __preinit_array_start = .; 39 | KEEP (*(.preinit_array)) 40 | __preinit_array_end = .; 41 | } >rom 42 | .init_array : { 43 | . = ALIGN(4); 44 | __init_array_start = .; 45 | KEEP (*(SORT(.init_array.*))) 46 | KEEP (*(.init_array)) 47 | __init_array_end = .; 48 | } >rom 49 | .fini_array : { 50 | . = ALIGN(4); 51 | __fini_array_start = .; 52 | KEEP (*(.fini_array)) 53 | KEEP (*(SORT(.fini_array.*))) 54 | __fini_array_end = .; 55 | } >rom 56 | 57 | /* 58 | * Another section used by C++ stuff, appears when using newlib with 59 | * 64bit (long long) printf support 60 | */ 61 | .ARM.extab : { 62 | *(.ARM.extab*) 63 | } >rom 64 | .ARM.exidx : { 65 | __exidx_start = .; 66 | *(.ARM.exidx*) 67 | __exidx_end = .; 68 | } >rom 69 | 70 | . = ALIGN(4); 71 | _etext = .; 72 | 73 | .data : { 74 | _data = .; 75 | *(.data*) /* Read-write initialized data */ 76 | . = ALIGN(4); 77 | _edata = .; 78 | } >ram AT >rom 79 | _data_loadaddr = LOADADDR(.data); 80 | 81 | .bss : { 82 | *(.bss*) /* Read-write zero initialized data */ 83 | *(COMMON) 84 | . = ALIGN(4); 85 | _ebss = .; 86 | } >ram 87 | 88 | /* 89 | * The .eh_frame section appears to be used for C++ exception handling. 90 | * You may need to fix this if you're using C++. 91 | */ 92 | /DISCARD/ : { *(.eh_frame) } 93 | 94 | . = ALIGN(4); 95 | end = .; 96 | } 97 | 98 | PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); 99 | 100 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/test.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2018-2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | #include 22 | 23 | volatile uint32_t * const ap_base = (volatile uint32_t * const)(0x90000000); 24 | volatile uint32_t * const smem = (volatile uint32_t * const)(0x03800000); 25 | volatile uint32_t * const data = (volatile uint32_t * const)(0x00000000); 26 | 27 | // These are just GPIO registers I'm using as generic un-cached memory. 28 | #define AP2MD_REG 0x10211160 29 | #define MD2AP_REG 0x10211150 30 | 31 | static char getchar(void) { 32 | char ret; 33 | 34 | // Wait for the AP to set the "data valid" flag. 35 | while ((ap_base[AP2MD_REG/4] & 0x100) == 0); 36 | 37 | ret = ap_base[AP2MD_REG/4] & 0xff; 38 | ap_base[AP2MD_REG/4] &= 0xfffffeff; 39 | 40 | return ret; 41 | } 42 | 43 | static void putchar(char c) { 44 | // Wait for the AP to clear the "data valid" flag. 45 | while ((ap_base[MD2AP_REG/4] & 0x100) != 0); 46 | 47 | ap_base[MD2AP_REG/4] &= 0xffffff00; 48 | ap_base[MD2AP_REG/4] |= c; 49 | ap_base[MD2AP_REG/4] |= 0x100; 50 | } 51 | 52 | static void handle_read() { 53 | // Get the address. 54 | uint32_t addr = 0; 55 | for (uint8_t i = 0; i < 4; i++) { 56 | uint8_t c = getchar(); 57 | addr |= c << (8 * i); 58 | } 59 | // Save the data at that address. 60 | uint32_t dword = data[addr/4]; 61 | // Send the data. 62 | for (uint8_t i = 0; i < 4; i++) { 63 | uint8_t c = (dword >> (8 * i)) & 0xff; 64 | putchar(c); 65 | } 66 | } 67 | 68 | static void handle_write() { 69 | // Get the address. 70 | uint32_t addr = 0; 71 | for (uint8_t i = 0; i < 4; i++) { 72 | uint8_t c = getchar(); 73 | addr |= c << (8 * i); 74 | } 75 | // Get the data. 76 | uint32_t dword = 0; 77 | for (uint8_t i = 0; i < 4; i++) { 78 | uint8_t c = getchar(); 79 | dword |= c << (8 * i); 80 | } 81 | // Write the data to the address. 82 | data[addr/4] = dword; 83 | } 84 | 85 | typedef enum { 86 | CMD_READ = 0x40, 87 | CMD_WRITE = 0x80, 88 | } cmd_t; 89 | 90 | void main(void) { 91 | // Enable JTAG on SD card port. 92 | ap_base[0x10211400/4] = 0x6db11249; 93 | 94 | // Clear registers. 95 | ap_base[AP2MD_REG/4] &= 0xfffffe00; 96 | ap_base[MD2AP_REG/4] &= 0xfffffe00; 97 | 98 | while (1) { 99 | char cmd = getchar(); 100 | 101 | switch (cmd) { 102 | case CMD_READ: 103 | handle_read(); 104 | break; 105 | case CMD_WRITE: 106 | handle_write(); 107 | break; 108 | default: 109 | break; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /SoC/MT6735/modemfw/vectors.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: BSD-3-Clause */ 2 | 3 | /**************************************************************************** 4 | * arch/arm/src/arm7-r/arm_vectortab.S 5 | * 6 | * Copyright (C) 2015 Gregory Nutt. All rights reserved. 7 | * Author: Gregory Nutt 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in 17 | * the documentation and/or other materials provided with the 18 | * distribution. 19 | * 3. Neither the name NuttX nor the names of its contributors may be 20 | * used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 30 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | * POSSIBILITY OF SUCH DAMAGE. 35 | * 36 | ****************************************************************************/ 37 | 38 | /**************************************************************************** 39 | * Included Files 40 | ****************************************************************************/ 41 | 42 | 43 | .file "vectors.S" 44 | .syntax unified 45 | 46 | 47 | /**************************************************************************** 48 | * Pre-processor Definitions 49 | ****************************************************************************/ 50 | 51 | /**************************************************************************** 52 | * Public Symbols 53 | ****************************************************************************/ 54 | 55 | .globl _vector_start 56 | .globl _vector_end 57 | 58 | .extern _start 59 | 60 | /**************************************************************************** 61 | * Assembly Macros 62 | ****************************************************************************/ 63 | 64 | /**************************************************************************** 65 | * Name: _vector_start 66 | * 67 | * Description: 68 | * Vector initialization block 69 | ****************************************************************************/ 70 | 71 | .section .vectors, "ax" 72 | .globl _vector_start 73 | 74 | /* These will be relocated to VECTOR_BASE. */ 75 | 76 | .thumb_func 77 | _vector_start: 78 | ldr pc, reset_handler /* 0x00: Reset */ 79 | ldr pc, other_handler /* 0x04: Undefined instruction */ 80 | ldr pc, other_handler /* 0x08: Software interrupt */ 81 | ldr pc, other_handler /* 0x0c: Prefetch abort */ 82 | ldr pc, other_handler /* 0x10: Data abort */ 83 | ldr pc, other_handler /* 0x14: Address exception (reserved) */ 84 | ldr pc, other_handler /* 0x18: IRQ */ 85 | ldr pc, other_handler /* 0x1c: FIQ */ 86 | 87 | wfi_loop: 88 | wfi 89 | b other_handler 90 | 91 | reset_handler: 92 | .long _start 93 | other_handler: 94 | .long wfi_loop 95 | 96 | .globl _vector_end 97 | _vector_end: 98 | .size _vector_start, . - _vector_start 99 | .end 100 | -------------------------------------------------------------------------------- /SoC/MT6735/mt6735.cfg: -------------------------------------------------------------------------------- 1 | # MediaTek MT6735 2 | # 3 | # This SoC has one cluster of four Cortex-A53 cores. 4 | # 5 | 6 | source [find target/swj-dp.tcl] 7 | 8 | set _CHIPNAME mt6735 9 | 10 | # 11 | # Main DAP 12 | # 13 | if { [info exists DAP_TAPID] } { 14 | set _DAP_TAPID $DAP_TAPID 15 | } else { 16 | set _DAP_TAPID 0x4ba00477 17 | } 18 | 19 | # declare the one JTAG tap to access the DAP 20 | swj_newdap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable 21 | 22 | # declare the 4 Cortex-A53 cores in the main cluster 23 | set _TARGETNAME $_CHIPNAME.cpu 24 | target create ${_TARGETNAME}0 aarch64 -chain-position $_CHIPNAME.dap -coreid 0 -dbgbase 0x80810000 -ctibase 0x80820000 25 | target create ${_TARGETNAME}1 aarch64 -chain-position $_CHIPNAME.dap -coreid 1 -dbgbase 0x80910000 -ctibase 0x80920000 -defer-examine 26 | target create ${_TARGETNAME}2 aarch64 -chain-position $_CHIPNAME.dap -coreid 2 -dbgbase 0x80a10000 -ctibase 0x80a20000 -defer-examine 27 | target create ${_TARGETNAME}3 aarch64 -chain-position $_CHIPNAME.dap -coreid 3 -dbgbase 0x80b10000 -ctibase 0x80b20000 -defer-examine 28 | target smp ${_TARGETNAME}0 ${_TARGETNAME}1 ${_TARGETNAME}2 ${_TARGETNAME}3 29 | -------------------------------------------------------------------------------- /SoC/MT6735/openocd.cfg: -------------------------------------------------------------------------------- 1 | source [find interface/jlink.cfg] 2 | 3 | adapter_khz 5000 4 | transport select jtag 5 | 6 | source mt6735.cfg 7 | 8 | init 9 | 10 | dap info 1 11 | dap info 2 12 | dap info 4 13 | -------------------------------------------------------------------------------- /SoC/MT6735/poke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell su -c /data/local/tmp/poke $@ 20 | -------------------------------------------------------------------------------- /SoC/MT6735/poke/.gitignore: -------------------------------------------------------------------------------- 1 | poke 2 | -------------------------------------------------------------------------------- /SoC/MT6735/poke/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2018 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | CC := arm-linux-gnueabihf-gcc 19 | CFLAGS := -Wall -Werror -static 20 | 21 | all: poke 22 | 23 | %: %.c 24 | $(CC) $(CFLAGS) -o $@ $< 25 | 26 | push: poke 27 | adb push $^ /data/local/tmp 28 | 29 | clean: 30 | rm -f poke 31 | 32 | .PHONY: all clean push 33 | -------------------------------------------------------------------------------- /SoC/MT6735/poke/poke.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2018 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | 29 | int main(int argc, char *argv[]) 30 | { 31 | int fd; 32 | void *map; 33 | volatile uint32_t *regs; 34 | 35 | uint32_t address; 36 | uint32_t reg_base; 37 | uint32_t reg_offset; 38 | uint32_t value; 39 | 40 | if (argc < 2 || argc > 3) { 41 | fprintf(stderr, "Usage: %s address [value]\n", argv[0]); 42 | return -1; 43 | } 44 | 45 | if (sscanf(argv[1], "%x", &address) != 1) { 46 | fprintf(stderr, "Error: address \"%s\" is not an integer\n", argv[1]); 47 | return -1; 48 | } 49 | 50 | if (address % 4 != 0) { 51 | fprintf(stderr, "Error: address 0x%08x must be a multiple of 4\n", address); 52 | return -1; 53 | } 54 | 55 | if (argc == 3) { 56 | if (sscanf(argv[2], "%x", &value) != 1) { 57 | fprintf(stderr, "Error: value \"%s\" is not an integer\n", argv[2]); 58 | return -1; 59 | } 60 | } 61 | 62 | size_t page_size = sysconf(_SC_PAGESIZE); 63 | reg_offset = address % page_size; 64 | reg_base = address - reg_offset; 65 | 66 | if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 67 | perror("can't open /dev/mem"); 68 | return -1; 69 | } 70 | 71 | map = mmap( 72 | NULL, 73 | page_size, 74 | PROT_READ|PROT_WRITE, 75 | MAP_SHARED, 76 | fd, 77 | reg_base 78 | ); 79 | if (map == (void *)(-1)) { 80 | perror("mmap failed"); 81 | return -1; 82 | } 83 | 84 | regs = (volatile uint32_t *)map; 85 | 86 | printf("*0x%08x = 0x%08x\n", address, regs[reg_offset/4]); 87 | if (argc == 3) { 88 | regs[reg_offset/4] = value; 89 | printf("*0x%08x = 0x%08x\n", address, regs[reg_offset/4]); 90 | } 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /SoC/MT6735/sd-jtag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | # Reconfigure the pinmux for the SD card pins (MSDC1) to enable JTAG. 20 | # Note that these pins can also be used for SWD, with TMS and TCK as 21 | # SWDIO and SWCLK respectively. 22 | # 23 | # Pin mapping: 24 | # +------+-------+ 25 | # | SD | JTAG | 26 | # |------+-------| 27 | # | DAT1 | TDO | 28 | # | DAT0 | TDI | 29 | # | CLK | TCK | 30 | # | CMD | TMS | 31 | # +------+-------+ 32 | 33 | 34 | adb shell su -c /data/local/tmp/poke 0x10211400 0x6db11249 35 | -------------------------------------------------------------------------------- /SoC/MT6735/start-android-test-settings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell am start -n com.android.settings/com.android.settings.TestingSettings 20 | -------------------------------------------------------------------------------- /SoC/MT6735/start-engineer-mode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: 0BSD 3 | 4 | # Copyright (C) 2018 by Forest Crossman 5 | # 6 | # Permission to use, copy, modify, and/or distribute this software for 7 | # any purpose with or without fee is hereby granted. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | # PERFORMANCE OF THIS SOFTWARE. 17 | 18 | 19 | adb shell am start -n com.mediatek.engineermode/com.mediatek.engineermode.EngineerMode 20 | -------------------------------------------------------------------------------- /SoC/MT6737M/README.md: -------------------------------------------------------------------------------- 1 | # MT6737M 2 | 3 | Primary target: [Orange Pi 4G-IoT][orangepi] 4 | 5 | 6 | [orangepi]: http://www.orangepi.org/Orange%20Pi%204G-IOT/ 7 | -------------------------------------------------------------------------------- /SoC/MT6737M/dump: -------------------------------------------------------------------------------- 1 | ../MT6735/dump -------------------------------------------------------------------------------- /SoC/MT6737M/dump.sh: -------------------------------------------------------------------------------- 1 | ../MT6735/dump.sh -------------------------------------------------------------------------------- /SoC/MT6737M/poke: -------------------------------------------------------------------------------- 1 | ../MT6735/poke -------------------------------------------------------------------------------- /SoC/MT6737M/poke.sh: -------------------------------------------------------------------------------- 1 | ../MT6735/poke.sh -------------------------------------------------------------------------------- /SoC/MT6737M/preloader/0001-fix-build.patch: -------------------------------------------------------------------------------- 1 | diff -ur a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/build.sh b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/build.sh 2 | --- a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/build.sh 2016-07-10 23:49:16.000000000 -0500 3 | +++ b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/build.sh 2018-05-02 03:11:16.647051077 -0500 4 | @@ -20,7 +20,7 @@ 5 | fi 6 | if [ -z ${PRELOADER_ROOT_DIR} ]; then 7 | if [ -z ${ANDROID_BUILD_TOP} ]; then 8 | - PRELOADER_ROOT_DIR=`pwd`/../../.. 9 | + PRELOADER_ROOT_DIR=`pwd`/../../../../../../ 10 | else 11 | PRELOADER_ROOT_DIR=${ANDROID_BUILD_TOP} 12 | fi 13 | -------------------------------------------------------------------------------- /SoC/MT6737M/preloader/0002-disable-BROM-lockout.patch: -------------------------------------------------------------------------------- 1 | diff -ur a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/security/trustzone/tz_sec_cfg.c b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/security/trustzone/tz_sec_cfg.c 2 | --- a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/security/trustzone/tz_sec_cfg.c 2016-07-10 23:49:16.000000000 -0500 3 | +++ b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/security/trustzone/tz_sec_cfg.c 2018-05-08 13:34:18.011486239 -0500 4 | @@ -30,25 +30,31 @@ 5 | void tz_sram_sec_init(u32 start) 6 | { 7 | /* Set Region Address Info */ 8 | +#if 0 9 | WRITE_REGISTER_UINT32(SRAMROM_SEC_ADDR, (start & SRAMROM_SEC_ADDR_MASK)); 10 | +#endif 11 | 12 | DBG_MSG("%s SRAMROM Secure Addr 0x%x\n", MOD, READ_REGISTER_UINT32(SRAMROM_SEC_ADDR)); 13 | DBG_MSG("%s SRAMROM Secure Control 0x%x\n", MOD, READ_REGISTER_UINT32(BOOTROM_PWR_CTRL)); 14 | 15 | /* Set permission for Region 0 */ 16 | +#if 0 17 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC0_DOM0_MASK, PERMIT_S_RW_NS_BLOCK << SRAMROM_SEC_SEC0_DOM0_SHIFT); 18 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC0_DOM1_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC0_DOM1_SHIFT); 19 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC0_DOM2_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC0_DOM2_SHIFT); 20 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC0_DOM3_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC0_DOM3_SHIFT); 21 | +#endif 22 | 23 | DBG_MSG("%s SRAMROM Secure Control 0x%x\n", MOD, READ_REGISTER_UINT32(BOOTROM_PWR_CTRL)); 24 | 25 | +#if 0 26 | /* Set permission for Region 1 */ 27 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC1_DOM0_MASK, PERMIT_S_RW_NS_RW << SRAMROM_SEC_SEC1_DOM0_SHIFT); 28 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC1_DOM1_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC1_DOM1_SHIFT); 29 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC1_DOM2_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC1_DOM2_SHIFT); 30 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC1_DOM3_MASK, PERMIT_S_BLOCK_NS_BLOCK << SRAMROM_SEC_SEC1_DOM3_SHIFT); 31 | TZ_SET_FIELD(BOOTROM_PWR_CTRL, SRAMROM_SEC_SEC1_EN_MASK, ENABLE_SEC_SEC1_PROTECTION << SRAMROM_SEC_SEC1_EN_SHIFT); 32 | +#endif 33 | 34 | DBG_MSG("%s SRAMROM Secure Control 0x%x\n", MOD, READ_REGISTER_UINT32(BOOTROM_PWR_CTRL)); 35 | } 36 | -------------------------------------------------------------------------------- /SoC/MT6737M/preloader/0003-JTAG-over-SD-pins.patch: -------------------------------------------------------------------------------- 1 | diff -ur a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/msdc.c b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/msdc.c 2 | --- a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/msdc.c 2016-07-10 23:49:16.000000000 -0500 3 | +++ b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/msdc.c 2018-05-02 04:21:32.729848036 -0500 4 | @@ -533,9 +533,12 @@ 5 | MSDC0_MODE_RSTB_MASK, 0x249); 6 | break; 7 | case 1: 8 | +// disable for JTAG-over-SD 9 | +#if 0 10 | MSDC_SET_FIELD(MSDC1_GPIO_MODE17_ADDR,MSDC1_MODE_CMD_MASK | MSDC1_MODE_CLK_MASK | MSDC1_MODE_DAT0_MASK | \ 11 | MSDC1_MODE_DAT1_MASK, 0x249); 12 | MSDC_SET_FIELD(MSDC1_GPIO_MODE18_ADDR,MSDC1_MODE_DAT2_MASK | MSDC1_MODE_DAT2_MASK, 0x9); 13 | +#endif 14 | break; 15 | #ifdef CFG_DEV_MSDC2 // Need sdio owner confirm 16 | 17 | diff -ur a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init/init.s b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init/init.s 18 | --- a/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init/init.s 2016-07-10 23:49:16.000000000 -0500 19 | +++ b/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init/init.s 2018-05-02 03:05:36.639874795 -0500 20 | @@ -130,6 +130,12 @@ 21 | MOV sp, r1 22 | 23 | entry : 24 | + /* Enable JTAG-over-SD */ 25 | + LDR r2, =0x10211400 /* MSDC1_GPIO_MODE17_ADDR */ 26 | + LDR r0, =0x6db11249 27 | + STR r0, [r2] 28 | + LDR r2, =0xDEADBEFF /* restore r2 */ 29 | + 30 | LDR r0, =bldr_args_addr 31 | B main 32 | 33 | -------------------------------------------------------------------------------- /SoC/MT6737M/preloader/README.md: -------------------------------------------------------------------------------- 1 | # preloader 2 | 3 | ## Build instructions 4 | 5 | **NOTE**: These instructions have only been tested with the 6 | `OrangePi_4G-IoT_Android6.0_V1.0` release. 7 | 8 | Apply patches to the Orange Pi 4G-IoT SDK/source release. Then, cd to 9 | the `code/vendor/mediatek/proprietary/bootable/bootloader/preloader` 10 | directory and run the following command: 11 | 12 | ```bash 13 | TARGET_PRODUCT=bd6737m_35g_b_m0 ./build.sh 14 | ``` 15 | 16 | The finished preloader should then be available at 17 | `code/out/target/product/bd6737m_35g_b_m0/obj/PRELOADER_OBJ/bin/preloader_bd6737m_35g_b_m0.bin` 18 | and can be flashed by either dd-ing it to the preloader partition using 19 | a shell on the device (adb or otherwise) or by using SPFT to flash the 20 | partition while the device is in download mode. See 21 | [Flashing the preloader](#flashing-the-preloader) for more information. 22 | 23 | ## Flashing the preloader 24 | 25 | First, download the [SP Flash Tool (SPFT)][spft] (from the 26 | [OrangePi 4G-IOT "Toolschain" download page][tool download page]) for 27 | your operating system. This is the tool that interacts with the 28 | "download mode" of the MediaTek BROM and preloader and can be used to 29 | read and write to the eMMC in that mode. 30 | 31 | If you're doing this on Windows, you'll probably need to install the 32 | [drivers][windows drivers] as well. Linux users don't need to install 33 | any drivers since the BROM and preloader download modes appear as a 34 | standard USB CDC-ACM serial port using the built-in `cdc_acm` driver. 35 | 36 | Next, download 37 | [IoT\_op\_smt\_hd720\_pcb\_v2\_v00\_eng\_20181030221529.tar.gz][archive of binaries] 38 | (from the 39 | [OrangePi 4G-IOT Android 6.0 download page][image download page]). This 40 | archive contains the SPFT scatter file for this device. It also contains 41 | the original preloader for the device, which you'll need in case the 42 | preloader gets erased from the device or your custom preloader fails to 43 | boot. 44 | 45 | If you haven't already, extract the SPFT and 46 | "IoT\_op\_smt\_hd720\_pcb\_v2\_v00\_eng\_20181030221529.tar.gz" archives 47 | and start SPFT. If you're using Linux, to start SPFT you'll need to run 48 | `chmod +x flash_tool.sh` to mark that script as executable and then you 49 | need to run `sudo ./flash_tool.sh`. If you don't want to run SPFT as 50 | root, you need to add udev rules to give your user permission to access 51 | serial ports. 52 | 53 | After starting SPFT, you should already be on the "Download" tab. Click 54 | the "choose" button next to the "Scatter-loading File" box to select the 55 | scatter file from the archive you downloaded earlier, 56 | `IoT_op_smt_hd720_pcb_v2/images/MT6737M_Android_scatter.txt`. After 57 | clicking "Open", the list of partitions should populate with all the 58 | checkboxes pre-selected. Deselect all the checkboxes except for the one 59 | for the "preloader" partition, then click the file path in the 60 | "Location" column for that partition to open up a file selection dialog. 61 | From there, select your custom preloader. 62 | 63 | Once you're ready to flash the preloader, first make sure that jumper J5 64 | has been removed from your device and that your device is unpowered and 65 | disconnected from your computer. Once you've confirmed this, click the 66 | "Download" button in SPFT. After that, plug your device into your 67 | computer via USB. If your device's preloader is functional, it should 68 | automatically be detected by SPFT and the preloader will start to be 69 | flashed to your device. Once you've flashed the preloader, you're done! 70 | 71 | If your device's preloader is not functional, you'll need to enter BROM 72 | download mode and flash from there. To do this, use a bit of wire to 73 | short the "KCOL0" test pad (found on the underside of the board) to 74 | ground, and keep the pin shorted while plugging in the USB cable to your 75 | computer. If you pressed the "Download" button previously, SPFT should 76 | now find the BROM in download mode and use that to flash the preloader 77 | to your device. 78 | 79 | [spft]: https://mega.nz/#F!WGwUhAZJ!xcc_4wd_UG_0OLruixz3ww!mCJG3DgT 80 | [tool download page]: http://www.orangepi.org/downloadresources/orangepi4G-IOT/2018-03-27/466a6d3bca476eca4dbd964b163739e2.html 81 | [windows drivers]: https://mega.nz/#F!WGwUhAZJ!xcc_4wd_UG_0OLruixz3ww!rGhSzJBL 82 | [archive of binaries]: https://drive.google.com/file/d/1Puti7wm7OFfa24b4lErAVgkEfbw5Nx5d/view 83 | [image download page]: http://www.orangepi.org/downloadresources/orangepi4G-IOT/2018-03-27/98c90c9ed1dc38b8e82b03c9ddb37ac7.html 84 | -------------------------------------------------------------------------------- /SoC/MT6771/mt8183_pcm_allinone.ksy: -------------------------------------------------------------------------------- 1 | meta: 2 | id: mt8183_pcm_allinone 3 | endian: le 4 | title: MediaTek MT8183 PCM All-in-One Binary 5 | license: CC0-1.0 6 | doc: "https://github.com/coreboot/coreboot/blob/a90854d429c5775d51021fbd488c9a2af153f250/src/soc/mediatek/mt8183/spm.c#L220-L226" 7 | seq: 8 | - id: firmware_size 9 | type: u2 10 | - id: binary 11 | size: 4 * firmware_size 12 | - id: descriptor 13 | type: pcm_desc 14 | - id: version 15 | type: strz 16 | encoding: ASCII 17 | types: 18 | pcm_desc: 19 | seq: 20 | - id: size 21 | type: u2 22 | - id: sess 23 | type: u1 24 | - id: replace 25 | type: u1 26 | - id: addr_2nd 27 | type: u2 28 | - id: reserved 29 | type: u2 30 | - id: vector 31 | type: u4 32 | repeat: expr 33 | repeat-expr: 16 34 | -------------------------------------------------------------------------------- /SoC/MT8183: -------------------------------------------------------------------------------- 1 | MT6771 -------------------------------------------------------------------------------- /SoC/common/README.md: -------------------------------------------------------------------------------- 1 | # Common SoC tools and information 2 | 3 | ## handshake 4 | 5 | This tool performs the USB download mode handshake. 6 | 7 | ## make_image.py 8 | 9 | This utility can be used to generate "preloader" images that can be 10 | written to eMMC devices and SD cards. 11 | 12 | ## parse_brom_log.py 13 | 14 | Use this to parse log messages output by the BROM. Documentation of the 15 | message format can be found in the [BROM notes][brom-notes]. 16 | 17 | ## socemu.py 18 | 19 | This tool uses the [Unicorn Engine][unicorn] to emulate MediaTek SoCs. 20 | It can also pass MMIO accesses to a real device over a serial interface. 21 | 22 | ## usbdl.py 23 | 24 | This is a tool to interact with the USB download mode of MediaTek SoCs. 25 | 26 | 27 | [brom-notes]: doc/BROM-Notes.md 28 | [unicorn]: https://www.unicorn-engine.org/ 29 | -------------------------------------------------------------------------------- /SoC/common/bmo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | 4 | # bmo.py - A library for interacting with SoCs running the serial monitor's 5 | # Binary MOde protocol. 6 | # Copyright (C) 2019-2020 Forest Crossman 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | import binascii 23 | import struct 24 | import time 25 | 26 | import serial 27 | 28 | 29 | class BmoInitError(Exception): 30 | pass 31 | 32 | class EchoBytesMismatchException(Exception): 33 | pass 34 | 35 | class NotEnoughDataException(Exception): 36 | pass 37 | 38 | class Bmo: 39 | commands = { 40 | 'EXIT': ord(b'\r'), 41 | 'READ': ord(b'R'), 42 | 'WRITE': ord(b'W'), 43 | 'SETBAUD': ord(b'S'), 44 | 'MEM_READ': ord(b'r'), 45 | 'MEM_WRITE': ord(b'w'), 46 | } 47 | 48 | def __init__(self, port, baudrate=115200, timeout=1, write_timeout=1, debug=False, verbose=False): 49 | self.debug = debug 50 | self.verbose = verbose or debug 51 | self.ser = serial.Serial(port, baudrate, timeout=timeout, write_timeout=write_timeout) 52 | self._send_bytes(b'\r' * 10) 53 | try: 54 | self._recv_bytes(1000) 55 | except: 56 | pass 57 | self._send_bytes(b'bmo\r', echo=True) 58 | expected_ack = b'\nOK\r\n' 59 | ack = self._recv_bytes(len(expected_ack)) 60 | if ack != expected_ack: 61 | raise BmoInitError("Invalid BMO ACK bytes: {} ({})".format(ack.hex(), repr(ack))) 62 | 63 | def close(self): 64 | self.ser.close() 65 | 66 | def _send_bytes(self, data, echo=False): 67 | data = bytes(data) 68 | if self.debug: 69 | print("-> {}".format(binascii.b2a_hex(data))) 70 | self.ser.write(data) 71 | if echo: 72 | echo_data = self.ser.read(len(data)) 73 | if self.debug: 74 | print("<- {}".format(binascii.b2a_hex(echo_data))) 75 | if echo_data != data: 76 | raise EchoBytesMismatchException 77 | 78 | def _recv_bytes(self, count): 79 | data = self.ser.read(count) 80 | if self.debug: 81 | print("<- {}".format(binascii.b2a_hex(data))) 82 | if len(data) != count: 83 | raise NotEnoughDataException 84 | return bytes(data) 85 | 86 | def get_dword(self): 87 | '''Read a little-endian 32-bit integer from the serial port.''' 88 | return struct.unpack(' 0x{:08x}".format(addr, word)) 111 | 112 | return word 113 | 114 | def writew(self, addr, word): 115 | '''Write a 32 bit word. 116 | 117 | addr: A 32-bit address as an int. 118 | word: The 32-bit word to write. 119 | ''' 120 | if self.verbose: 121 | print("0x{:08x} <= 0x{:08x}".format(addr, word)) 122 | 123 | self._send_bytes([self.commands['WRITE']]) 124 | self.put_dword(addr) 125 | self.put_dword(word) 126 | 127 | def setbaud(self, baudrate): 128 | '''Sets the baudrate.''' 129 | 130 | self._send_bytes([self.commands['SETBAUD']]) 131 | self.put_dword(baudrate) 132 | self.close() 133 | 134 | def memory_read(self, addr, count, fast=False, print_speed=False): 135 | '''Read a range of memory to a byte array. 136 | 137 | addr: A 32-bit address as an int. 138 | count: The length of data to read, in bytes. 139 | ''' 140 | word_count = count//4 141 | if (count % 4) > 0: 142 | word_count += 1 143 | 144 | data = b'' 145 | if fast: 146 | aligned_count = word_count * 4 147 | 148 | self._send_bytes([self.commands['MEM_READ']]) 149 | self.put_dword(addr) 150 | self.put_dword(aligned_count) 151 | 152 | block_size = 0x1000 153 | cbs = block_size 154 | start_ns = time.perf_counter_ns() 155 | for i in range(0, aligned_count, block_size): 156 | if aligned_count - i < cbs: 157 | cbs = aligned_count - i 158 | data += self._recv_bytes(cbs) 159 | time.sleep(0.0001) 160 | end_ns = time.perf_counter_ns() 161 | else: 162 | start_ns = time.perf_counter_ns() 163 | for i in range(word_count): 164 | data += struct.pack(' 0: 186 | padded_data += b'\0' * (4 - remaining_bytes) 187 | 188 | if fast: 189 | self._send_bytes([self.commands['MEM_WRITE']]) 190 | self.put_dword(addr) 191 | self.put_dword(len(padded_data)) 192 | 193 | block_size = 0x1000 194 | start_ns = time.perf_counter_ns() 195 | for i in range(0, len(padded_data), block_size): 196 | self._send_bytes(padded_data[i:i+block_size]) 197 | time.sleep(0.0001) 198 | end_ns = time.perf_counter_ns() 199 | else: 200 | start_ns = time.perf_counter_ns() 201 | for i in range(0, len(padded_data), 4): 202 | self.writew(addr + i, struct.unpack_from(' 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | all: hello-aarch64 mode-switch write-sequence 19 | 20 | hello-aarch64 mode-switch write-sequence: 21 | $(MAKE) -C $@ 22 | 23 | clean: 24 | $(MAKE) -C hello-aarch64 clean 25 | $(MAKE) -C mode-switch clean 26 | $(MAKE) -C write-sequence clean 27 | 28 | .PHONY: all clean hello-aarch64 mode-switch write-sequence 29 | -------------------------------------------------------------------------------- /SoC/common/demo/hello-aarch64/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.map 4 | *.o 5 | build_info.c 6 | -------------------------------------------------------------------------------- /SoC/common/demo/hello-aarch64/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | # Copyright (C) 2019-2020 Forest Crossman 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | 19 | PREFIX := aarch64-linux-gnu- 20 | AS := $(PREFIX)as 21 | ASFLAGS := -march=armv8-a 22 | CC := $(PREFIX)gcc 23 | CFLAGS := -Wall -march=armv8-a -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -Os 24 | LD := $(PREFIX)ld 25 | LDFLAGS := -T linker.ld -Map hello-aarch64.map 26 | OBJCOPY := $(PREFIX)objcopy 27 | OBJDUMP := $(PREFIX)objdump 28 | 29 | all: hello-aarch64.bin hello-aarch64.elf 30 | 31 | %.o: %.c 32 | $(CC) $(CFLAGS) -c -o $@ $< 33 | 34 | %.o: %.S 35 | $(AS) $(ASFLAGS) -o $@ $< 36 | 37 | build_info.c: build_info.inc.c 38 | sed s/BUILD_VERSION/$(shell printf "r%s.g%s" "$(shell git rev-list --count HEAD)" "$(shell git rev-parse --short HEAD)")/g $< | \ 39 | sed s/BUILD_TIME/$(shell date -u '+%FT%H:%M:%SZ')/g > $@ 40 | 41 | hello-aarch64.elf: init.o main.o build_info.o 42 | $(LD) $(LDFLAGS) -o $@ $^ 43 | 44 | %.bin: %.elf 45 | $(OBJCOPY) -S -O binary $< $@ 46 | chmod -x $@ 47 | 48 | disasm-bin: hello-aarch64.bin 49 | $(OBJDUMP) -maarch64 -b binary -D $< 50 | 51 | disasm-elf: hello-aarch64.elf 52 | $(OBJDUMP) -d $< 53 | 54 | clean: 55 | rm -f *.bin *.elf *.map *.o build_info.c 56 | 57 | .PHONY: all clean exec disasm-bin disasm-elf build_info.c 58 | -------------------------------------------------------------------------------- /SoC/common/demo/hello-aarch64/build_info.inc.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | char const * const build_version = "BUILD_VERSION"; 22 | char const * const build_time = "BUILD_TIME"; 23 | -------------------------------------------------------------------------------- /SoC/common/demo/hello-aarch64/init.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019-2020 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | .section .init, "ax" 22 | .global _start 23 | _start: 24 | mov x0, xzr 25 | mov x1, xzr 26 | mov x2, xzr 27 | mov x3, xzr 28 | mov x4, xzr 29 | mov x5, xzr 30 | mov x6, xzr 31 | mov x7, xzr 32 | mov x8, xzr 33 | mov x9, xzr 34 | mov x10, xzr 35 | mov x11, xzr 36 | mov x12, xzr 37 | mov x13, xzr 38 | mov x14, xzr 39 | mov x15, xzr 40 | mov x16, xzr 41 | mov x17, xzr 42 | mov x18, xzr 43 | mov x19, xzr 44 | mov x20, xzr 45 | mov x21, xzr 46 | mov x22, xzr 47 | mov x23, xzr 48 | mov x24, xzr 49 | mov x25, xzr 50 | mov x26, xzr 51 | mov x27, xzr 52 | mov x28, xzr 53 | mov x29, xzr 54 | mov x30, xzr 55 | 56 | _stack_init: 57 | ldr x0, =_stack_base 58 | mov sp, x0 59 | 60 | _data_init: 61 | ldr x0, =_data_loadaddr 62 | ldr x1, =_data_start 63 | ldr x2, =_data_end 64 | _data_init_loop: 65 | cmp x1, x2 66 | beq _bss_init 67 | ldp x3, x4, [x0], 16 68 | stp x3, x4, [x1], 16 69 | b _data_init_loop 70 | 71 | _bss_init: 72 | ldr x2, =_bss_end 73 | _bss_init_loop: 74 | cmp x1, x2 75 | beq _cleanup 76 | stp xzr, xzr, [x1], 16 77 | b _bss_init_loop 78 | 79 | _cleanup: 80 | mov x0, xzr 81 | mov x1, xzr 82 | mov x2, xzr 83 | mov x3, xzr 84 | mov x4, xzr 85 | 86 | _jump_to_main: 87 | bl main 88 | 89 | _wfi_loop: 90 | wfi 91 | b _wfi_loop 92 | -------------------------------------------------------------------------------- /SoC/common/demo/hello-aarch64/linker.ld: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-3.0-or-later */ 2 | 3 | /* 4 | * Copyright (C) 2019-2020 Forest Crossman 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | MEMORY 22 | { 23 | rom (rx) : ORIGIN = 0x00201000, LENGTH = 0x00030000 24 | ram (rw) : ORIGIN = 0x00231000, LENGTH = 0x0000f000 25 | } 26 | 27 | ENTRY(_start) 28 | 29 | _stack_base = ORIGIN(ram) + LENGTH(ram) - 16; 30 | 31 | SECTIONS 32 | { 33 | .text : { 34 | *(.init) 35 | *(.text*) 36 | . = ALIGN(16); 37 | *(.rodata*) 38 | . = ALIGN(16); 39 | } >rom 40 | 41 | .data : { 42 | _data_start = .; 43 | *(.data*) 44 | . = ALIGN(16); 45 | _data_end = .; 46 | } >ram AT >rom 47 | _data_loadaddr = LOADADDR(.data); 48 | 49 | .bss : { 50 | *(.bss*) 51 | . = ALIGN(16); 52 | _bss_end = .; 53 | } >ram 54 | 55 | /DISCARD/ : { *(.eh_frame) } 56 | 57 | . = ALIGN(16); 58 | end = .; 59 | } 60 | -------------------------------------------------------------------------------- /SoC/common/demo/mode-switch/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.map 4 | *.o 5 | -------------------------------------------------------------------------------- /SoC/common/demo/mode-switch/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2019, 2021 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | PREFIX := arm-none-eabi- 19 | AS := $(PREFIX)as 20 | ASFLAGS := -march=armv7-a 21 | CC := $(PREFIX)gcc 22 | #CFLAGS := -march=armv7-a -mthumb -mfloat-abi=soft -fpie -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -Os 23 | CFLAGS := -march=armv7-a -mfloat-abi=soft -fpie -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -Os 24 | LD := $(PREFIX)ld 25 | LDFLAGS := -T linker.ld -Map mode-switch.map 26 | OBJCOPY := $(PREFIX)objcopy 27 | OBJDUMP := $(PREFIX)objdump 28 | 29 | all: mode-switch.bin mode-switch.elf 30 | 31 | %.o: %.c 32 | $(CC) $(CFLAGS) -c -o $@ $< 33 | 34 | %.o: %.S 35 | $(AS) $(ASFLAGS) -o $@ $< 36 | 37 | mode-switch.elf: init.o main.o 38 | $(LD) $(LDFLAGS) -o $@ $^ 39 | 40 | %.bin: %.elf 41 | $(OBJCOPY) -S -O binary $< $@ 42 | chmod -x $@ 43 | 44 | disasm-bin: mode-switch.bin 45 | $(OBJDUMP) -marm -b binary -D $< 46 | 47 | disasm-elf: mode-switch.elf 48 | $(OBJDUMP) -d $< 49 | 50 | clean: 51 | rm -f *.bin *.elf *.map *.o 52 | 53 | .PHONY: all clean exec disasm-bin disasm-elf 54 | -------------------------------------------------------------------------------- /SoC/common/demo/mode-switch/init.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2021 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | .syntax unified 21 | 22 | .section .init, "ax" 23 | .global _start 24 | _start: 25 | mov r0, #0 26 | mov r1, #0 27 | mov r2, #0 28 | mov r3, #0 29 | mov r4, #0 30 | mov r5, #0 31 | mov r6, #0 32 | mov r7, #0 33 | mov r8, #0 34 | mov r9, #0 35 | mov r10, #0 36 | mov r11, #0 37 | mov r12, #0 38 | mov lr, #0 39 | 40 | _stack_init: 41 | ldr sp, =_stack_base 42 | 43 | _data_init: 44 | ldr r0, =_data_loadaddr 45 | ldr r1, =_data_start 46 | ldr r2, =_data_end 47 | _data_init_loop: 48 | cmp r1, r2 49 | beq _bss_init 50 | ldr r3, [r0], #4 51 | str r3, [r1], #4 52 | b _data_init_loop 53 | 54 | _bss_init: 55 | ldr r2, =_bss_end 56 | mov r3, #0 57 | _bss_init_loop: 58 | cmp r1, r2 59 | beq _cleanup 60 | str r3, [r1], #4 61 | b _bss_init_loop 62 | 63 | _cleanup: 64 | mov r0, #0 65 | mov r1, #0 66 | mov r2, #0 67 | 68 | _jump_to_main: 69 | bl main 70 | 71 | _wfi_loop: 72 | wfi 73 | b _wfi_loop 74 | -------------------------------------------------------------------------------- /SoC/common/demo/mode-switch/linker.ld: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2021 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | MEMORY 21 | { 22 | rom (rx) : ORIGIN = 0x00200000, LENGTH = 0x00000C00 23 | ram (rw) : ORIGIN = 0x00200C00, LENGTH = 0x00000400 24 | } 25 | 26 | ENTRY(_start) 27 | 28 | _stack_base = ORIGIN(ram) + LENGTH(ram) - 8; 29 | 30 | SECTIONS 31 | { 32 | .text : { 33 | *(.init) 34 | *(.text*) 35 | . = ALIGN(4); 36 | *(.rodata*) 37 | . = ALIGN(4); 38 | } >rom 39 | 40 | .data : { 41 | _data_start = .; 42 | *(.data*) 43 | . = ALIGN(4); 44 | _data_end = .; 45 | } >ram AT >rom 46 | _data_loadaddr = LOADADDR(.data); 47 | 48 | .bss : { 49 | *(.bss*) 50 | . = ALIGN(4); 51 | _bss_end = .; 52 | } >ram 53 | 54 | /DISCARD/ : { *(.eh_frame) } 55 | 56 | . = ALIGN(4); 57 | end = .; 58 | } 59 | -------------------------------------------------------------------------------- /SoC/common/demo/mode-switch/main.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2019-2021 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | static uint32_t volatile * const mem = (uint32_t volatile * const)(0x00000000); 24 | static uint32_t volatile * const sram = (uint32_t volatile * const)(0x00100000); 25 | static uint32_t volatile * const l2_sram = (uint32_t volatile * const)(0x00200000); 26 | 27 | #define UART_BASE 0x11002000 28 | #define UART_RBR (UART_BASE + 0x00) 29 | #define UART_THR (UART_BASE + 0x00) 30 | #define UART_LSR (UART_BASE + 0x14) 31 | 32 | #define UART_LSR_DR (1 << 0) 33 | #define UART_LSR_THRE (1 << 5) 34 | 35 | static char getchar(void) { 36 | char ret; 37 | 38 | // Wait for the UART to assert the "data ready" flag. 39 | while ((mem[UART_LSR/4] & UART_LSR_DR) == 0); 40 | 41 | ret = mem[UART_RBR/4] & 0xff; 42 | 43 | return ret; 44 | } 45 | 46 | static void putchar(char c) { 47 | // Wait for the UART to become ready. 48 | while ((mem[UART_LSR/4] & UART_LSR_THRE) == 0); 49 | 50 | if (c == '\n') 51 | putchar('\r'); 52 | 53 | mem[UART_THR/4] = c; 54 | } 55 | 56 | static void print(const char * buf) { 57 | for (size_t i = 0; ; i++) { 58 | if (buf[i] == 0) 59 | break; 60 | putchar(buf[i]); 61 | } 62 | } 63 | 64 | static void println(const char * buf) { 65 | print(buf); 66 | putchar('\n'); 67 | } 68 | 69 | static void wfi() { 70 | asm("wfi"); 71 | } 72 | 73 | static const uint32_t get_rvbar(void) { 74 | uint32_t soc_id = mem[0x08000000/4]; 75 | switch(soc_id) { 76 | case 0x0279: 77 | // MT6797 78 | return 0x10220038; 79 | case 0x0321: 80 | // MT6735 81 | return 0x10200038; 82 | case 0x0326: 83 | // MT6750 84 | return 0x10200038; 85 | case 0x0335: 86 | // MT6737M 87 | return 0x10200038; 88 | case 0x0788: 89 | // MT6771/MT8183 90 | return 0x0c530038; 91 | case 0x8163: 92 | // MT8163 93 | return 0x10200038; 94 | default: 95 | return 0x10200038; 96 | } 97 | } 98 | 99 | static void jump_to_aarch64(uint32_t addr) { 100 | uint32_t rvbar = get_rvbar(); 101 | asm( 102 | "str %[addr], [%[rvbar]]\n" 103 | "dsb sy\n" 104 | "isb sy\n" 105 | "mrc 15, 0, r0, cr12, cr0, 2\n" 106 | "orr r0, r0, #3\n" 107 | "mcr 15, 0, r0, cr12, cr0, 2\n" 108 | "isb sy\n" 109 | : /* No outputs. */ 110 | : [addr] "r" (addr), [rvbar] "r" (rvbar) 111 | : "r0" 112 | ); 113 | 114 | println("Switching to AArch64!"); 115 | while(1) { 116 | wfi(); 117 | } 118 | } 119 | 120 | void main(void) { 121 | println("Executing mode-switch..."); 122 | jump_to_aarch64(0x00201000); 123 | while (1) { 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /SoC/common/demo/write-sequence/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | *.map 4 | *.o 5 | -------------------------------------------------------------------------------- /SoC/common/demo/write-sequence/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2020 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | PREFIX := arm-none-eabi- 19 | AS := $(PREFIX)as 20 | ASFLAGS := -march=armv7-a 21 | LD := $(PREFIX)ld 22 | LDFLAGS := -T linker.ld -Map write-sequence.map 23 | OBJCOPY := $(PREFIX)objcopy 24 | OBJDUMP := $(PREFIX)objdump 25 | 26 | all: write-sequence.bin 27 | 28 | %.o: %.S 29 | $(AS) $(ASFLAGS) -o $@ $< 30 | 31 | %.elf: %.o 32 | $(LD) $(LDFLAGS) -o $@ $^ 33 | 34 | %.bin: %.elf 35 | $(OBJCOPY) -S -O binary $< $@ 36 | chmod -x $@ 37 | 38 | disasm-bin: write-sequence.bin 39 | $(OBJDUMP) -marm -b binary -D $< 40 | 41 | disasm-elf: write-sequence.elf 42 | $(OBJDUMP) -d $< 43 | 44 | clean: 45 | rm -f *.bin *.elf *.map *.o 46 | 47 | .PHONY: all clean disasm-bin disasm-elf 48 | -------------------------------------------------------------------------------- /SoC/common/demo/write-sequence/linker.ld: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2020 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | MEMORY 21 | { 22 | rom (rx) : ORIGIN = 0x00100A00, LENGTH = 0x00000A00 23 | } 24 | 25 | ENTRY(_start) 26 | 27 | SECTIONS 28 | { 29 | .text : { 30 | *(.text.start) 31 | . = ALIGN(4); 32 | } >rom 33 | 34 | /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(.eh_frame) } 35 | } 36 | -------------------------------------------------------------------------------- /SoC/common/demo/write-sequence/write-sequence.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2020 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | .syntax unified 21 | 22 | .section .text.start, "ax" 23 | .global _start 24 | _start: 25 | push {r0, r1, r2, r3, r4, lr} 26 | 27 | // Send the USB response to avoid a timeout. 28 | adr r3, args + 0 29 | ldr r3, [r3] // Address of send_usb_response function, with Thumb bit set appropriately. 30 | cmp r3, 0 31 | beq reg_write_init 32 | mov r0, 0 // send_usb_response arg 0. 33 | mov r1, 0 // send_usb_response arg 1. 34 | mov r2, 1 // send_usb_response arg 2. 35 | blx r3 36 | 37 | reg_write_init: 38 | adr r2, args + 8 // Pointer to the operations array. 39 | mov r3, 0 40 | adr r4, args + 4 41 | ldr r4, [r4] // The number of operations. 42 | 43 | reg_write_loop: 44 | cmp r3, r4 45 | beq done 46 | ldrd r0, r1, [r2], 8 47 | str r1, [r0] 48 | add r3, r3, 1 49 | b reg_write_loop 50 | 51 | done: 52 | pop {r0, r1, r2, r3, r4, pc} 53 | 54 | args: 55 | -------------------------------------------------------------------------------- /SoC/common/doc/BROM-Notes.md: -------------------------------------------------------------------------------- 1 | # BROM Notes 2 | 3 | 4 | ## Decoding the BROM log 5 | 6 | - `[DL] XXXXXXXX YYYYYYYY AABBCC` 7 | - Download mode info? 8 | - `XXXXXXXX`: USB DL timeout in ms. 0xffffffff if there is no 9 | timeout. 10 | - `YYYYYYYY`: The contents of register `BOOT_MISC0`, which is used as 11 | the USB DL mode flag register. 12 | - `(0x444C << 16) | ((timeout_seconds & 0x3fff) << 2) | 1` 13 | - The upper 16 bits are the magic ("DL"), and the lowest bit is the 14 | enable. Both must be set to enable flag-triggered USB DL mode. 15 | - The timeout is in seconds, and must be less than 16383 (0x3fff). 16 | - A timeout of 0x3fff means "no timeout". 17 | - `AA`: 0x00 if there is no DL mode timeout, 0x01 if there is a valid 18 | timeout. 19 | - `BB`: Unknown, usually 0x03 or 0x07. 20 | - `CC`: `SEJ + 0x00` (`SEJ_CON`) bits [3:0] when bits [3:0] are 1, 2, 21 | or 3, 0x04 if bits [3:0] are 7, and 0xff otherwise. 22 | - `BP: XXXX XXXX [YYYY]` 23 | - Boot parameters? 24 | - `XXXXXXXX`: 32-bit bitfield of boot parameters. 25 | - 0x00000001: Preloader found on boot medium. 26 | - 0x00000002: USB synced for DL mode. 27 | - 0x00000008: JTAG is disabled. 28 | - 0x00000010: USB failed to sync for DL mode. 29 | - 0x00000020: UART synced for DL mode. 30 | - 0x00000040: UART failed to sync for DL mode. 31 | - 0x00000080: `YYYY` is non-zero. 32 | - 0x00000100: Unknown. 33 | - 0x00000200: `SEJ + 0xc0` (`SEJ_CON1`) bits [11:8] are not clear. 34 | - 0x04000000: Preloader on boot medium is 64-bit. 35 | - 0x08000000: USB DL HS (High Speed?) enabled. 36 | - 0x10000000: `gfh_brom_cfg.gfh_brom_cfg_v3.reserved3` bit 0 and 37 | `gfh_brom_cfg.gfh_brom_cfg_v3.flags.reserved1` are set, or 38 | `M_SW_RES` bit 6 is set. 39 | - 0x20000000: `M_SW_RES` bit 5 set. 40 | - 0x40000000: `M_SW_RES` bit 4 set. 41 | - 0x80000000: `M_SW_RES` bit 3 set. 42 | - `YYYY`: Preloader offset. The BROM searches for preloaders on 43 | 2048-byte boundaries, so this number will be the byte offset of 44 | the preloader divided by 2048. 45 | - `Fn: XXXX YYYY` 46 | - Failure information? 47 | - `n`: Boot mode ID. 48 | - 0: RAM (literally loading a GFH FILE_INFO image from RAM, as if 49 | it were a disk) 50 | - 3: MSDC0 (eMMC) 51 | - 5: MSDC1 (SD) 52 | - `XXXX`: Most recent status code. 53 | - `YYYY`: Previous status code. 54 | - `G0: XXXX YYZZ` 55 | - `XXXX`: Bits [15:0] of `gfh_brom_cfg.gfh_brom_cfg_v3.flags`. 56 | - `YY`: `gfh_brom_cfg.gfh_brom_cfg_v3.usbdl_bulk_com_support`. 57 | - `ZZ`: `gfh_brom_cfg.gfh_brom_cfg_v3.reserved1`. 58 | - `nn: XXXX YYYY` 59 | - `nn`: An integer that starts at zero and auto-increments after 60 | every `nn` line printed. e.g., `00`, `01`, `02`, etc. 61 | - `XXXX`: Status code. 62 | - `YYYY`: Extra context-specific data. 63 | - `T0: XXXX XXXX [YYYY]` 64 | - Boot time? 65 | - `XXXXXXXX`: 32-bit BROM execution time in ms. 66 | - `YYYY`: Lower 16 bits of the JTAG delay in ms. 67 | - The JTAG delay is the amount of time the BROM will busy-wait 68 | before executing the main function. This gives a developer time 69 | to connect a JTAG dongle and halt the CPU. 70 | - `Vn: XXXX YYYY [ZZZZ]` 71 | - `n`: Bootloader descriptor index (0-7). 72 | - `XXXX`: Most recent status code (`code_1`). 73 | - `YYYY`: Previous status code (`code_2`). 74 | - `ZZZZ`: Bootloader descriptor `bl_type`. 75 | 76 | 77 | ## Hashes and sizes of various SoC BROMs 78 | 79 | - MT6735 80 | - Size: 65536 bytes 81 | - MD5: `4111199bba0afe2437d1082c1dcc4bb2` 82 | - SHA1: `fadb35104a805974d1e8514b2c78d083e8aa8a32` 83 | - SHA256: `72ccdd7dece9cf295f76cae3c7a98a2815835e9b8c2b769a6813ef1d84c38f9d` 84 | - SHA512: `3da06abbf9eafa83a79f4b9502e02c7983db349d293bd6c9655e056c7c5660c6cae2537bcd9a016adfec5db06fc27b412dda426b5a65af9592b69f1e830e4589` 85 | - MT6737M 86 | - Size: 65536 bytes 87 | - MD5: `e258ecea1ec865500c750b309cf1859a` 88 | - SHA1: `169d7983a8f709bb6b32398c200b969026da6fb8` 89 | - SHA256: `179dc0aa7c65fb85cb1e9e9c95ea2c9424eecc6b9267a343c7c9511cd546267a` 90 | - SHA512: `fdba3cf632adc23bebde115c765db1a0969c1c377a93f736a0e02f17d9c4ccd62f1d9081f26f1a0386b42da24806a8c63d5656f3a60c1461a55c938e6fa24dde` 91 | - MT6750 92 | - Size: 65536 bytes 93 | - MD5: `dcdaabb035912aff377911bd30e4c4b6` 94 | - SHA1: `fab382a2ef9d4ee502aea47176183323ebf68130` 95 | - SHA256: `0b4afa40e03b128cca6cd2a72ed1abd998893b0f8574cb3080f4f292d70a5eda` 96 | - SHA512: `fea2277261913ffca06b56ab911a1b60c68d373a849f6be1f0b21b8d6dd50e4c654737e2050cb15359ce2374b58d75a62bcc5748c2be66f8651357723a195b9b` 97 | - MT6753 98 | - Size: 65536 bytes 99 | - MD5: `8e71645f8b3667ff5ff71bf5c3b095d4` 100 | - SHA1: `169d7983a8f709bb6b32398c200b969026da6fb8` 101 | - SHA256: `b1d57b13fddfe14ddf4842671b06840471e74e7245e36db7140ca0656f23151e` 102 | - SHA512: `d9b5b0c4323f085f9ac07779fe296c2f63ead44d08eac38b496b31c425c37654fec39e739b07f0e23423ac6f2e2cc51fb5607b9474d3642f991099cbc7fb5890` 103 | - MT6771/MT8183 104 | - Size: 98304 bytes 105 | - MD5: `88f78c13206b84fe6063966b775aba5f` 106 | - SHA1: `cbcf5f2cb4bc9e71bbe8cee41cccea2d51b947d7` 107 | - SHA256: `0b84ebc200233fdfd4284407be63cce4ccbd1c3ceb3ad939e167c523da688ac2` 108 | - SHA512: `462672ccb63f4f1e633846380c6506257fe8266926ea881a9671092f8841b1ec92ff3ad0a66e9379f1cc02aeb79ab3fdad6961249aa5d504633dc689e830906d` 109 | - MT6797 110 | - Size: 81920 bytes 111 | - MD5: `9c0b56cbfbd3d1a2e0b278e120123b87` 112 | - SHA1: `80f64a862b63bccd2ea0a8a15a3f3c5404ff1971` 113 | - SHA256: `8192a6b554dea105e8f731771e7955b21709f97febdbbf593ccd4f57f5db9bf1` 114 | - SHA512: `64f1ff741f862ca4b02c3896ad8ac8c5f287e4e2b5d3a59d24e81897c1045182caef0c4c32ceea4b7cf5305a7d80aaca38aabb84ded4df9803d1f90ca9131233` 115 | - MT8163 116 | - Size: 81920 bytes 117 | - MD5: `9ad089946a4b117a036a6165a22d846a` 118 | - SHA1: `7543c1f93e1525bcaa14c1acffef9ac9deb7cb31` 119 | - SHA256: `0969b97512db38fde33e89e9e1fdfbc5508624015c74390d69719ef9d457ef8f` 120 | - SHA512: `744e498414ce6339ab33b594726200cf7f683f0162fea1c8d92bd3c418c140c48fdc0a90525d59fb6abee3160fc652eff9840617b5eb172576b20fbffb79a2c1` 121 | -------------------------------------------------------------------------------- /SoC/common/doc/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | This directory is for miscellaneous unofficial documentation. 4 | -------------------------------------------------------------------------------- /SoC/common/handshake/.gitignore: -------------------------------------------------------------------------------- 1 | handshake 2 | -------------------------------------------------------------------------------- /SoC/common/handshake/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: 0BSD 2 | 3 | # Copyright (C) 2019 by Forest Crossman 4 | # 5 | # Permission to use, copy, modify, and/or distribute this software for 6 | # any purpose with or without fee is hereby granted. 7 | # 8 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 | # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 13 | # PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 | # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | 17 | 18 | CFLAGS := -Wall -Wextra -Werror 19 | 20 | all: handshake 21 | 22 | %: %.c 23 | $(CC) $(CFLAGS) -o $@ $< 24 | 25 | clean: 26 | rm -f handshake 27 | 28 | .PHONY: all clean 29 | -------------------------------------------------------------------------------- /SoC/common/handshake/README.md: -------------------------------------------------------------------------------- 1 | # USB download mode handshake tool 2 | 3 | The `handshake` utility waits for the selected serial port to appear, 4 | then immediately connects to it and tries to send a handshake sequence. 5 | Because this is a timing-sensitive operation, and because the port setup 6 | requires particular TTY settings, this program is written in C instead 7 | of Python. 8 | 9 | ``` 10 | Usage: ./handshake port 11 | ``` 12 | -------------------------------------------------------------------------------- /SoC/common/handshake/handshake.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: 0BSD */ 2 | 3 | /* 4 | * Copyright (C) 2019 by Forest Crossman 5 | * 6 | * Permission to use, copy, modify, and/or distribute this software for 7 | * any purpose with or without fee is hereby granted. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 | * PERFORMANCE OF THIS SOFTWARE. 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int set_interface_attribs(int fd, int speed) 30 | { 31 | struct termios tty; 32 | 33 | if (tcgetattr(fd, &tty) < 0) { 34 | perror("Error from tcgetattr()"); 35 | return -1; 36 | } 37 | 38 | cfsetospeed(&tty, (speed_t)speed); 39 | cfsetispeed(&tty, (speed_t)speed); 40 | 41 | //tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ 42 | //tty.c_cflag &= ~CSIZE; 43 | //tty.c_cflag |= CS8; /* 8-bit characters */ 44 | //tty.c_cflag &= ~PARENB; /* no parity bit */ 45 | //tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ 46 | //tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ 47 | 48 | /* setup for non-canonical mode */ 49 | //tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 50 | //tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 51 | //tty.c_oflag &= ~OPOST; 52 | 53 | /* Settings found using strace. */ 54 | tty.c_iflag=0; 55 | tty.c_oflag=0x4; 56 | tty.c_cflag=0x10b2; 57 | tty.c_lflag=0xa30; 58 | 59 | /* fetch bytes as they become available */ 60 | tty.c_cc[VMIN] = 1; 61 | tty.c_cc[VTIME] = 0; 62 | 63 | if (tcsetattr(fd, TCSANOW, &tty) != 0) { 64 | perror("Error from tcsetattr()"); 65 | return -1; 66 | } 67 | return 0; 68 | } 69 | 70 | int main(int argc, char *argv[]) 71 | { 72 | char *portname; 73 | int fd; 74 | 75 | if (argc != 2) { 76 | fprintf(stderr, "Usage: %s port\n", argv[0]); 77 | return -1; 78 | } 79 | portname = argv[1]; 80 | 81 | printf("Waiting to open \"%s\"...\n", portname); 82 | while (0 > (fd = open(portname, O_RDWR | O_NOCTTY | /*O_NONBLOCK*/ O_SYNC))) { 83 | usleep(50000); 84 | } 85 | if (fd < 0) { 86 | fprintf(stderr, "Error opening \"%s\": %s\n", portname, strerror(errno)); 87 | return -1; 88 | } 89 | /* Baudrate 115200, 8 bits, no parity, 1 stop bit. */ 90 | if (0 > set_interface_attribs(fd, B115200)) { 91 | return -1; 92 | } 93 | 94 | tcsendbreak(fd, 0); 95 | tcflush(fd, TCIOFLUSH); 96 | tcsendbreak(fd, 0); 97 | tcflush(fd, TCIOFLUSH); 98 | 99 | int connected = 0; 100 | const uint8_t start[4] = { 0xa0, 0x0a, 0x50, 0x05 }; 101 | const uint8_t expected[4] = { 0x5f, 0xf5, 0xaf, 0xfa }; 102 | while (connected == 0) { 103 | for (int i = 0; i < 4; i++) { 104 | printf("Send: 0x%02x\n", start[i]); 105 | int wlen = write(fd, &start[i], 1); 106 | if (wlen < 0) { 107 | perror("Error from write()"); 108 | return -1; 109 | } 110 | tcdrain(fd); 111 | uint8_t val; 112 | int rlen = read(fd, &val, 1); 113 | if (rlen < 0) { 114 | perror("Error from read()"); 115 | return -1; 116 | } 117 | printf("Recv: 0x%02x\n", val); 118 | if (val != expected[i]) { 119 | if (0 > set_interface_attribs(fd, B115200)) { 120 | return -1; 121 | } 122 | break; 123 | } else if (i == 3) { 124 | connected = 1; 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /SoC/common/init.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # init.py - A tool for initializing SoCs by poking registers over serial 5 | # Copyright (C) 2019-2020 Forest Crossman 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import argparse 22 | import sys 23 | 24 | from bmo import Bmo 25 | 26 | 27 | if __name__ == "__main__": 28 | parser = argparse.ArgumentParser() 29 | parser.add_argument('port', type=str, help="The serial port you want to connect to.") 30 | parser.add_argument('-b', '--baudrate', type=int, default=115200, help="The baud rate you want to connect at. Default: 115200") 31 | parser.add_argument('-s', '--baudrate-next', type=int, default=115200, help="The baud rate you want to switch to. Default: 115200") 32 | args = parser.parse_args() 33 | 34 | bmo = Bmo(args.port, baudrate=args.baudrate, debug=False) 35 | if args.baudrate_next != args.baudrate: 36 | print("Switching to baudrate to {}...".format(args.baudrate_next)) 37 | bmo.setbaud(args.baudrate_next) 38 | 39 | bmo = Bmo(args.port, baudrate=args.baudrate_next, debug=False) 40 | 41 | #bmo.debug = True 42 | #bmo.debug = False 43 | 44 | print(bmo.memory_read(0, 0x10000, print_speed=True).hex()) 45 | -------------------------------------------------------------------------------- /SoC/common/openocd.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | """ 4 | OpenOCD RPC example, covered by GNU GPLv3 or later 5 | Copyright (C) 2014 Andreas Ortmann (ortmann@finf.uni-hannover.de) 6 | 7 | """ 8 | 9 | import socket 10 | 11 | class OpenOcd: 12 | COMMAND_TOKEN = '\x1a' 13 | def __init__(self, tclRpcIp="127.0.0.1", tclRpcPort=6666, bufferSize=40960000, verbose=False): 14 | self.verbose = verbose 15 | self.tclRpcIp = tclRpcIp 16 | self.tclRpcPort = tclRpcPort 17 | self.bufferSize = bufferSize 18 | 19 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 20 | 21 | def __enter__(self): 22 | self.sock.connect((self.tclRpcIp, self.tclRpcPort)) 23 | return self 24 | 25 | def __exit__(self, type, value, traceback): 26 | try: 27 | self.send("exit") 28 | finally: 29 | self.sock.close() 30 | 31 | def send(self, cmd): 32 | """Send a command string to TCL RPC. Return the result that was read.""" 33 | data = (cmd + OpenOcd.COMMAND_TOKEN).encode("utf-8") 34 | if self.verbose: 35 | print("<- ", data) 36 | 37 | self.sock.send(data) 38 | return self._recv() 39 | 40 | def _recv(self): 41 | """Read from the stream until the token (\x1a) was received.""" 42 | data = bytes() 43 | while True: 44 | chunk = self.sock.recv(self.bufferSize) 45 | data += chunk 46 | if bytes(OpenOcd.COMMAND_TOKEN, encoding="utf-8") in chunk: 47 | break 48 | 49 | if self.verbose: 50 | print("-> ", data) 51 | 52 | data = data.decode("utf-8").strip() 53 | data = data[:-1] # strip trailing \x1a 54 | 55 | return data 56 | -------------------------------------------------------------------------------- /SoC/common/parse_brom_log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # parse_brom_log.py - A tool for parsing logs printed by the boot ROM 5 | # Copyright (C) 2021 Forest Crossman 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import fileinput 22 | import re 23 | import struct 24 | 25 | 26 | DL_REGEX = r"\[DL\] (?P[0-9A-F]{8}) (?P[0-9A-F]{8}) (?P[0-9A-F]{2})(?P[0-9A-F]{2})(?P[0-9A-F]{2})" 27 | MSG_REGEX = r"(?P[0-9A-Z]{2}): (?P[0-9A-F]{4}) (?P[0-9A-F]{4})( \[(?P[0-9A-F]{4})\])?" 28 | 29 | 30 | def get_orig(match): 31 | span = match.span() 32 | orig = match.string[span[0]:span[1]] 33 | return orig 34 | 35 | def parse_dl(groups): 36 | usbdl_timeout_ms = int(groups['x'], 16) 37 | usbdl_mode = int(groups['y'], 16) 38 | flag = usbdl_mode >> 16 39 | timeout_s = (usbdl_mode >> 2) & 0x3fff 40 | enable = usbdl_mode & 1 41 | a = int(groups['a'], 16) 42 | b = int(groups['b'], 16) 43 | c = int(groups['c'], 16) 44 | 45 | usbdl_timeout_string = "{} ms".format(usbdl_timeout_ms) 46 | if usbdl_timeout_ms == 0xffffffff: 47 | usbdl_timeout_string = "None" 48 | 49 | mode_timeout_string = "{} s".format(timeout_s) 50 | if timeout_s == 0x3fff: 51 | mode_timeout_string = "None" 52 | 53 | aa_string = { 54 | 0x00: "No DL mode timeout.", 55 | 0x01: "Valid DL mode timeout set.", 56 | }.get(a, "UNKNOWN") 57 | 58 | print(" - {}: USB DL timeout: {}".format(groups['x'], usbdl_timeout_string)) 59 | print(" - {}: USB DL mode".format(groups['y'])) 60 | print(" - Flag: {}".format("Present" if flag == 0x444C else "Absent")) 61 | print(" - Timeout: {}".format(mode_timeout_string)) 62 | print(" - Enabled: {}".format(True if enable else False)) 63 | print(" - {}: {}".format(groups['a'], aa_string)) 64 | print(" - {}".format(groups['b'])) 65 | print(" - {}".format(groups['c'])) 66 | 67 | def parse_bp(groups): 68 | flags_hi = int(groups['x'], 16) 69 | flags_lo = int(groups['y'], 16) 70 | offset = int(groups['z'], 16) 71 | flags = (flags_hi << 16) | flags_lo 72 | 73 | flag_bits = { 74 | 0x00000001: "Preloader found on boot medium.", 75 | 0x00000002: "USB synced for DL mode.", 76 | 0x00000008: "JTAG is disabled.", 77 | 0x00000010: "USB failed to sync for DL mode.", 78 | 0x00000020: "UART synced for DL mode.", 79 | 0x00000040: "UART failed to sync for DL mode.", 80 | 0x00000080: "Preloader offset is non-zero.", 81 | 0x00000200: "SEJ + 0xc0 (SEJ_CON1) bits [11:8] are not clear.", 82 | 0x04000000: "Preloader on boot medium is 64-bit.", 83 | 0x08000000: "USB DL HS (High Speed?) enabled.", 84 | 0x10000000: "gfh_brom_cfg.gfh_brom_cfg_v3.reserved3 bit 0 and gfh_brom_cfg.gfh_brom_cfg_v3.flags.reserved1 are set: or M_SW_RES bit 6 is set.", 85 | 0x20000000: "M_SW_RES bit 5 set.", 86 | 0x40000000: "M_SW_RES bit 4 set.", 87 | 0x80000000: "M_SW_RES bit 3 set.", 88 | } 89 | 90 | print(" - {} {}: Flags".format(groups['x'], groups['y'])) 91 | for bit in range(32): 92 | mask = 1 << bit 93 | if flags & mask: 94 | description = flag_bits.get(mask, "Unknown.") 95 | print(" - {}".format(description)) 96 | print(" - {}: Preloader offset: {} bytes".format(groups['z'], offset * 2048)) 97 | 98 | def parse_fn(groups): 99 | mode = int(groups['type'][1], 16) 100 | code_1 = int(groups['x'], 16) 101 | code_2 = int(groups['y'], 16) 102 | 103 | mode_string = { 104 | 0: "RAM", 105 | 3: "MSDC0 (eMMC)", 106 | 5: "MSDC1 (SD)", 107 | }.get(mode, "UNKNOWN") 108 | 109 | print(" - {}: Boot mode ID: {}".format(mode, mode_string)) 110 | print(" - {}: Most recent status code: 0x{:04x}".format(groups['x'], code_1)) 111 | print(" - {}: Previous status code: 0x{:04x}".format(groups['y'], code_2)) 112 | 113 | def parse_g0(groups): 114 | y = int(groups['y'], 16) 115 | usbdl_bulk_com_support = y >> 8 116 | reserved1 = y & 0xff 117 | 118 | print(" - {}: Lower 16 bits of the BROM config flags.".format(groups['x'])) 119 | print(" - {0:02X}: USB DL bulk communications support: {0}".format(usbdl_bulk_com_support)) 120 | print(" - {0:02X}: BROM config reserved1: {0}".format(reserved1)) 121 | 122 | def parse_nn(groups): 123 | counter = int(groups['type'], 16) 124 | code_1 = int(groups['x'], 16) 125 | code_2 = int(groups['y'], 16) 126 | 127 | print(" - {}: Message counter: {}".format(groups['type'], counter)) 128 | print(" - {}: Status code: 0x{:04x}".format(groups['x'], code_1)) 129 | print(" - {}: Extra context-specific data: 0x{:04x}".format(groups['y'], code_2)) 130 | 131 | def parse_t0(groups): 132 | time_hi = int(groups['x'], 16) 133 | time_lo = int(groups['y'], 16) 134 | jtag_delay = int(groups['z'], 16) 135 | boot_time = (time_hi << 16) | time_lo 136 | 137 | print(" - {} {}: BROM execution time: {} ms".format(groups['x'], groups['y'], boot_time)) 138 | print(" - {}: JTAG delay % 65536: {} ms".format(groups['z'], jtag_delay)) 139 | 140 | def parse_vn(groups): 141 | bd_idx = int(groups['type'][1], 10) 142 | code_1 = int(groups['x'], 16) 143 | code_2 = int(groups['y'], 16) 144 | bl_type = int(groups['z'], 16) 145 | 146 | bl_type_string = { 147 | 0x0000: "gfh_file_none", 148 | 0x0001: "arm_bl", 149 | 0x0002: "arm_ext_bl", 150 | 0x0003: "dualmac_dsp_bl", 151 | 0x0004: "sctrl_cert", 152 | 0x0005: "tool_auth", 153 | 0x0006: "file_mtk_reserved1", 154 | 0x0007: "epp", 155 | 0x0008: "file_mtk_reserved2", 156 | 0x0009: "file_mtk_reserved3", 157 | 0x000a: "root_cert", 158 | 0x000b: "ap_bl", 159 | }.get(bl_type, "unknown") 160 | 161 | print(" - {0}: Bootloader descriptor index: {0}".format(bd_idx)) 162 | print(" - {}: Most recent status code: 0x{:04x}".format(groups['x'], code_1)) 163 | print(" - {}: Previous status code: 0x{:04x}".format(groups['y'], code_2)) 164 | print(" - {}: Bootloader descriptor bl_type: {}".format(groups['z'], bl_type_string.upper())) 165 | 166 | def parse_msg(groups): 167 | msg_type = groups['type'] 168 | 169 | matchers = ( 170 | (r"BP", parse_bp), 171 | (r"F[0-9A-F]", parse_fn), 172 | (r"G0", parse_g0), 173 | (r"[0-9][0-9A-F]", parse_nn), 174 | (r"T0", parse_t0), 175 | (r"V[0-9]", parse_vn), 176 | ) 177 | 178 | for regex, handler in matchers: 179 | match = re.fullmatch(regex, msg_type) 180 | if match: 181 | handler(groups) 182 | break 183 | 184 | def main(): 185 | matchers = ( 186 | (re.compile(DL_REGEX), parse_dl), 187 | (re.compile(MSG_REGEX), parse_msg), 188 | ) 189 | for line in fileinput.input(): 190 | for regex, handler in matchers: 191 | match = regex.search(line) 192 | if match: 193 | print(get_orig(match)) 194 | groups = match.groupdict() 195 | handler(groups) 196 | break 197 | 198 | 199 | if __name__ == "__main__": 200 | main() 201 | -------------------------------------------------------------------------------- /SoC/common/parse_efuses.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # parse_efuses.py - A tool for parsing e-fuse dumps 5 | # Copyright (C) 2021 Forest Crossman 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import argparse 22 | import struct 23 | 24 | 25 | SOCS = { 26 | "MT6737M": { 27 | 'efusec_base': 0x10206000, 28 | 'efuses': ( 29 | # name, offset, size 30 | ("EFUSEC_CON", 0x000, 4), 31 | ("EFUSEC_PGMT", 0x004, 4), 32 | ("EFUSEC_BPKEY", 0x008, 4), 33 | ("CTRL", 0x020, 4), 34 | ("LOCK", 0x028, 4), 35 | ("USB_PID", 0x030, 4), 36 | ("USB_VID", 0x038, 4), 37 | ("SPARE0", 0x040, 4), 38 | ("SPARE1", 0x044, 4), 39 | ("SPARE2", 0x048, 4), 40 | ("SPARE3", 0x04C, 4), 41 | ("SPARE4", 0x050, 4), 42 | ("SEC_CTRL", 0x060, 4), 43 | ("SEC_LOCK", 0x068, 4), 44 | ("AC_KEY", 0x070, 16), 45 | ("SBC_PUBK_HASH", 0x090, 32), 46 | ("M_HW_RES0", 0x100, 4), 47 | ("M_HW_RES1", 0x104, 4), 48 | ("M_HW_RES2", 0x108, 4), 49 | ("M_SW_RES", 0x120, 4), 50 | ("M_LOCK", 0x128, 4), 51 | ("M_SEC_CTRL", 0x130, 4), 52 | ("M_SEC_LOCK", 0x138, 4), 53 | ("HUID", 0x140, 8), 54 | ("HUK", 0x160, 16), 55 | ("M_HW_RES3", 0x170, 4), 56 | ("M_HW_RES4", 0x174, 4), 57 | ("M_HW_RES5", 0x178, 4), 58 | ("M_HW_RES6", 0x17C, 4), 59 | ("M_HW_RES7", 0x180, 4), 60 | ("M_HW_RES8", 0x184, 4), 61 | ("M_HW_RES9", 0x188, 4), 62 | ("M_SRM_RP0", 0x190, 4), 63 | ("M_SRM_RP1", 0x194, 4), 64 | ("M_SRM_RP2", 0x198, 4), 65 | ("M_SRM_RP3", 0x19C, 4), 66 | ("M_SRM_RP4", 0x1A0, 4), 67 | ("ECC_DATA1", 0x380, 4), 68 | ("ECC_DATA2", 0x384, 4), 69 | ("MULTI_BIT_ECC_DATA_WRITE", 0x400, 4), 70 | ("DBG_MODE", 0x404, 4), 71 | ("LAST_BLOW_DATA", 0x408, 4), 72 | ("EFUSE_MR_KEY", 0x40C, 4), 73 | ), 74 | 'efuse_bits': ( 75 | # offset, name, lsb, width 76 | (0x28, 'usb_id_lock', 1, 1), 77 | (0x28, 'com_ctrl_lock', 2, 1), 78 | (0x44, '3g_disable', 0, 1), 79 | (0x60, 'hw_jtag_disabled', 0, 1), 80 | (0x60, 'sbc_enabled', 1, 1), 81 | (0x60, 'daa_enabled', 2, 1), 82 | (0x60, 'sla_enabled', 3, 1), 83 | (0x60, 'sw_jtag_enabled', 6, 1), 84 | (0x60, 'root_cert_enabled', 7, 1), 85 | (0x60, 'jtag_brom_lock_disabled', 9, 1), 86 | (0x68, 'sbc_pubk_hash_lock', 0, 1), 87 | (0x68, 'ackey_lock', 1, 1), 88 | (0x68, 'sec_attr_lock', 2, 1), 89 | ), 90 | }, 91 | "MT8163": { 92 | 'efusec_base': 0x10206000, 93 | 'efuses': ( 94 | # name, offset, size 95 | ("EFUSEC_CON", 0x000, 4), 96 | ("EFUSEC_PGMT", 0x004, 4), 97 | ("EFUSEC_BPKEY", 0x008, 4), 98 | ("CTRL", 0x020, 4), 99 | ("LOCK", 0x028, 4), 100 | ("USB_PID", 0x030, 4), 101 | ("USB_VID", 0x038, 4), 102 | ("SPARE0", 0x040, 4), 103 | ("SPARE1", 0x044, 4), 104 | ("SPARE2", 0x048, 4), 105 | ("SPARE3", 0x04C, 4), 106 | ("SPARE4", 0x050, 4), 107 | ("SEC_CTRL", 0x060, 4), 108 | ("SEC_LOCK", 0x068, 4), 109 | ("AC_KEY", 0x070, 16), 110 | ("SBC_PUBK_HASH", 0x090, 32), 111 | ("M_HW_RES0", 0x100, 4), 112 | ("M_HW_RES1", 0x104, 4), 113 | ("M_HW_RES2", 0x108, 4), 114 | ("M_SW_RES", 0x120, 4), 115 | ("M_LOCK", 0x128, 4), 116 | ("M_SEC_CTRL", 0x130, 4), 117 | ("M_SEC_LOCK", 0x138, 4), 118 | ("HUID", 0x140, 8), 119 | ("HUK", 0x160, 16), 120 | ("M_HW_RES3", 0x170, 4), 121 | ("M_HW_RES4", 0x174, 4), 122 | ("M_HW_RES5", 0x178, 4), 123 | ("M_HW_RES6", 0x17C, 4), 124 | ("M_HW_RES7", 0x180, 4), 125 | ("M_HW_RES8", 0x184, 4), 126 | ("M_HW_RES9", 0x188, 4), 127 | ("M_SRM_RP0", 0x190, 4), 128 | ("M_SRM_RP1", 0x194, 4), 129 | ("M_SRM_RP2", 0x198, 4), 130 | ("M_SRM_RP3", 0x19C, 4), 131 | ("M_SRM_RP4", 0x1A0, 4), 132 | ("ECC_DATA1", 0x380, 4), 133 | ("ECC_DATA2", 0x384, 4), 134 | ("MULTI_BIT_ECC_DATA_WRITE", 0x400, 4), 135 | ("DBG_MODE", 0x404, 4), 136 | ("LAST_BLOW_DATA", 0x408, 4), 137 | ("EFUSE_MR_KEY", 0x40C, 4), 138 | ), 139 | 'efuse_bits': ( 140 | # offset, name, lsb, width 141 | (0x44, '3g_disable', 0, 1), 142 | (0x60, 'sbc_enabled', 1, 1), 143 | (0x60, 'daa_enabled', 2, 1), 144 | (0x60, 'sla_enabled', 3, 1), 145 | ), 146 | }, 147 | } 148 | 149 | 150 | def main(): 151 | parser = argparse.ArgumentParser() 152 | parser.add_argument('efuse_dump', type=str, help="The EFUSE dump you want to parse.") 153 | parser.add_argument('-S', '--soc', type=str, choices=SOCS.keys(), default="MT6737M", help="The SoC the EFUSE dump corresponds to. Default: MT6737M") 154 | args = parser.parse_args() 155 | 156 | soc = SOCS[args.soc] 157 | base = soc['efusec_base'] 158 | 159 | dump = open(args.efuse_dump, 'rb').read() 160 | 161 | for (name, offset, size) in soc['efuses']: 162 | addr = base + offset 163 | if size == 2: 164 | print("0x{:08x} ({}): 0x{:04x}".format(addr, name, struct.unpack_from(' 0 173 | value = (struct.unpack_from('> lsb) & ((1 << width) - 1) 174 | print(" [{}]: {}: {}".format(lsb, bits_name, value)) 175 | 176 | 177 | if __name__ == "__main__": 178 | main() 179 | -------------------------------------------------------------------------------- /SoC/common/pcm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-License-Identifier: GPL-3.0-or-later 3 | 4 | # pcm.py - A tool for interacting with the PCM by poking registers over serial 5 | # Copyright (C) 2020-2021 Forest Crossman 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import argparse 22 | import os 23 | import struct 24 | import sys 25 | import time 26 | 27 | from bmo import Bmo 28 | 29 | 30 | class Pcm(Bmo): 31 | def __init__(self, *args, spm_base=None, **kwargs): 32 | self.spm_base = spm_base 33 | if not self.spm_base: 34 | raise ValueError("Error: SPM base address \"spm_base\" has not been set.") 35 | 36 | super().__init__(*args, **kwargs) 37 | 38 | def soc_reset(self): 39 | # Reset the whole SoC. 40 | self.writew(0x10212000, 0x22000000 | 0x10 | 0x4) 41 | self.writew(0x10212000 + 0x14, 0x1209) 42 | 43 | self.close() 44 | 45 | def pcm_reset(self): 46 | # Enable the PCM for configuration. 47 | self.writew(self.spm_base + 0x000, (0x0b16 << 16) | 1) 48 | 49 | # PCM reset. 50 | pcm_fsm_state = self.readw(self.spm_base + 0x3c4) 51 | print("FSM state: 0x{:08x}".format(pcm_fsm_state)) 52 | self.writew(self.spm_base + 0x310, (0x0b16 << 16) | (1 << 15)) 53 | self.writew(self.spm_base + 0x310, (0x0b16 << 16)) 54 | pcm_fsm_state = self.readw(self.spm_base + 0x3c4) 55 | if pcm_fsm_state != 0x2848490: 56 | raise Exception("PCM reset failed: 0x{:08x}".format(pcm_fsm_state)) 57 | 58 | # Configure PCM. 59 | self.writew(self.spm_base + 0x310, (0x0b16 << 16) | (1 << 3)) 60 | self.writew(self.spm_base + 0x314, (0x0b16 << 16) | (1 << 12) | (1 << 11) | (1 << 10) | (1 << 3)) 61 | 62 | # Clear IM pointer and length. 63 | self.writew(self.spm_base + 0x318, 0) 64 | self.writew(self.spm_base + 0x31c, 0) 65 | 66 | # Configure clocks. 67 | self.writew(self.spm_base + 0x400, (1 << 1) | (1 << 0) | (1 << 2) | (1 << 6) | (1 << 12) | 68 | (1 << 10) | (1 << 9) | (1 << 18)) 69 | 70 | # Mask and clear sleep interrupts. 71 | self.writew(self.spm_base + 0x900, 0xff0c) 72 | self.writew(self.spm_base + 0x904, 0xc) 73 | 74 | # Clear PCM interrupts. 75 | self.writew(self.spm_base + 0x3e4, 0xff) 76 | 77 | # Power on MD32 SRAM. 78 | self.writew(self.spm_base + 0x2c8, 0xff0) 79 | 80 | def pcm_run(self): 81 | # Kick IM. 82 | con0 = self.readw(self.spm_base + 0x310) & ~((1 << 1) | (1 << 0)) 83 | self.writew(self.spm_base + 0x310, con0 | (0x0b16 << 16) | (1 << 1)) 84 | self.writew(self.spm_base + 0x310, con0 | (0x0b16 << 16)) 85 | 86 | # Kick PCM. 87 | con0 = self.readw(self.spm_base + 0x310) & ~((1 << 1) | (1 << 0)) 88 | self.writew(self.spm_base + 0x310, con0 | (0x0b16 << 16) | (1 << 0)) 89 | self.writew(self.spm_base + 0x310, con0 | (0x0b16 << 16)) 90 | 91 | # Set the pause mask. 92 | self.writew(self.spm_base + 0x354, 0xffffffff) 93 | 94 | # Enable CPU power down and dormant. 95 | self.writew(self.spm_base + 0x400, self.readw(self.spm_base + 0x400) & ~(1 << 14)) 96 | 97 | def reg_read(self, reg : int): 98 | return self.readw(self.spm_base + 0x380 + 4 * reg) 99 | 100 | def regs_read(self): 101 | for i in range(16): 102 | yield self.reg_read(i) 103 | 104 | def print_regs(self): 105 | regs = ["R{}: 0x{:08x}".format(reg, value) for reg, value in enumerate(self.regs_read())] 106 | print(", ".join(regs[:4])) 107 | print(", ".join(regs[4:8])) 108 | print(", ".join(regs[8:12])) 109 | print(", ".join(regs[12:])) 110 | 111 | def im_read(self, word_addr : int, word_count : int): 112 | word_array = [] 113 | for i in range(word_count): 114 | self.writew(self.spm_base + 0x3c8, (1 << 31) | (word_addr + i)) 115 | word_array.append(struct.pack('