Move to linux
This commit is contained in:
parent
6d1b49ae02
commit
ebe3b20f58
91 changed files with 23251 additions and 23149 deletions
26
.gitignore
vendored
26
.gitignore
vendored
|
|
@ -1,14 +1,14 @@
|
|||
*.o
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.lst
|
||||
*.map
|
||||
*.txt
|
||||
*.exe
|
||||
*.out
|
||||
dev_resource/
|
||||
compress_test.bat
|
||||
*.cmm
|
||||
*.bak
|
||||
*.o
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.lst
|
||||
*.map
|
||||
*.txt
|
||||
*.exe
|
||||
*.out
|
||||
dev_resource/
|
||||
compress_test.bat
|
||||
*.cmm
|
||||
*.bak
|
||||
build/*.has
|
||||
18
.vscode/c_cpp_properties.json
vendored
Normal file
18
.vscode/c_cpp_properties.json
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "linux-gcc-x64",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"compilerPath": "/bin/gcc",
|
||||
"cStandard": "${default}",
|
||||
"cppStandard": "${default}",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compilerArgs": [
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
24
.vscode/launch.json
vendored
Normal file
24
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "C/C++ Runner: Debug Session",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false,
|
||||
"cwd": "/home/wrapper/work/dumpnow_dcc",
|
||||
"program": "/home/wrapper/work/dumpnow_dcc/build/Debug/outDebug",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerPath": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
76
.vscode/settings.json
vendored
76
.vscode/settings.json
vendored
|
|
@ -1,10 +1,70 @@
|
|||
{
|
||||
"makefile.configureOnOpen": true,
|
||||
"files.associations": {
|
||||
"*.ejs": "html",
|
||||
"*.c": "c",
|
||||
"*.s": "arm",
|
||||
"*.h": "c",
|
||||
"cstdint": "c"
|
||||
}
|
||||
"makefile.configureOnOpen": true,
|
||||
"files.associations": {
|
||||
"*.ejs": "html",
|
||||
"*.c": "c",
|
||||
"*.s": "arm",
|
||||
"*.h": "c",
|
||||
"cstdint": "c"
|
||||
},
|
||||
"C_Cpp_Runner.msvcBatchPath": "",
|
||||
"C_Cpp_Runner.cCompilerPath": "gcc",
|
||||
"C_Cpp_Runner.cppCompilerPath": "g++",
|
||||
"C_Cpp_Runner.debuggerPath": "gdb",
|
||||
"C_Cpp_Runner.cStandard": "",
|
||||
"C_Cpp_Runner.cppStandard": "",
|
||||
"C_Cpp_Runner.useMsvc": false,
|
||||
"C_Cpp_Runner.warnings": [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wpedantic",
|
||||
"-Wshadow",
|
||||
"-Wformat=2",
|
||||
"-Wcast-align",
|
||||
"-Wconversion",
|
||||
"-Wsign-conversion",
|
||||
"-Wnull-dereference"
|
||||
],
|
||||
"C_Cpp_Runner.msvcWarnings": [
|
||||
"/W4",
|
||||
"/permissive-",
|
||||
"/w14242",
|
||||
"/w14287",
|
||||
"/w14296",
|
||||
"/w14311",
|
||||
"/w14826",
|
||||
"/w44062",
|
||||
"/w44242",
|
||||
"/w14905",
|
||||
"/w14906",
|
||||
"/w14263",
|
||||
"/w44265",
|
||||
"/w14928"
|
||||
],
|
||||
"C_Cpp_Runner.enableWarnings": true,
|
||||
"C_Cpp_Runner.warningsAsError": false,
|
||||
"C_Cpp_Runner.compilerArgs": [],
|
||||
"C_Cpp_Runner.linkerArgs": [],
|
||||
"C_Cpp_Runner.includePaths": [],
|
||||
"C_Cpp_Runner.includeSearch": [
|
||||
"*",
|
||||
"**/*"
|
||||
],
|
||||
"C_Cpp_Runner.excludeSearch": [
|
||||
"**/build",
|
||||
"**/build/**",
|
||||
"**/.*",
|
||||
"**/.*/**",
|
||||
"**/.vscode",
|
||||
"**/.vscode/**"
|
||||
],
|
||||
"C_Cpp_Runner.useAddressSanitizer": false,
|
||||
"C_Cpp_Runner.useUndefinedSanitizer": false,
|
||||
"C_Cpp_Runner.useLeakSanitizer": false,
|
||||
"C_Cpp_Runner.showCompilationTime": false,
|
||||
"C_Cpp_Runner.useLinkTimeOptimization": false,
|
||||
"C_Cpp_Runner.msvcSecureNoWarnings": false,
|
||||
"clangd.fallbackFlags": [
|
||||
"-I${workspaceRoot}"
|
||||
]
|
||||
}
|
||||
210
build/ram.ld
210
build/ram.ld
|
|
@ -1,105 +1,105 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
****************************************************************************
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 30.03.06 mifi First Version
|
||||
****************************************************************************/
|
||||
|
||||
ENTRY(ResetHandler)
|
||||
SEARCH_DIR(.)
|
||||
|
||||
/*
|
||||
* Define stack size here
|
||||
*/
|
||||
FIQ_STACK_SIZE = 0x0100;
|
||||
IRQ_STACK_SIZE = 0x0100;
|
||||
ABT_STACK_SIZE = 0x0100;
|
||||
UND_STACK_SIZE = 0x0100;
|
||||
SVC_STACK_SIZE = 0x0100;
|
||||
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : org = 0x00000000, len = 1024k
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not change the next code
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.vectors);
|
||||
. = ALIGN(4);
|
||||
*(.init);
|
||||
. = ALIGN(4);
|
||||
*(.text);
|
||||
. = ALIGN(4);
|
||||
*(.rodata);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(4);
|
||||
*(.glue_7t);
|
||||
. = ALIGN(4);
|
||||
*(.glue_7);
|
||||
. = ALIGN(4);
|
||||
etext = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
edata = .;
|
||||
_edata = .;
|
||||
PROVIDE (__data_end = .);
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__bss_end = .);
|
||||
|
||||
. = ALIGN(256);
|
||||
|
||||
PROVIDE (__stack_start = .);
|
||||
|
||||
PROVIDE (__stack_fiq_start = .);
|
||||
. += FIQ_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_fiq_end = .);
|
||||
|
||||
PROVIDE (__stack_irq_start = .);
|
||||
. += IRQ_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_irq_end = .);
|
||||
|
||||
PROVIDE (__stack_abt_start = .);
|
||||
. += ABT_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_abt_end = .);
|
||||
|
||||
PROVIDE (__stack_und_start = .);
|
||||
. += UND_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_und_end = .);
|
||||
|
||||
PROVIDE (__stack_svc_start = .);
|
||||
. += SVC_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_svc_end = .);
|
||||
PROVIDE (__stack_end = .);
|
||||
PROVIDE (__heap_start = .);
|
||||
} > ram
|
||||
|
||||
}
|
||||
/*** EOF ***/
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
****************************************************************************
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 30.03.06 mifi First Version
|
||||
****************************************************************************/
|
||||
|
||||
ENTRY(ResetHandler)
|
||||
SEARCH_DIR(.)
|
||||
|
||||
/*
|
||||
* Define stack size here
|
||||
*/
|
||||
FIQ_STACK_SIZE = 0x0100;
|
||||
IRQ_STACK_SIZE = 0x0100;
|
||||
ABT_STACK_SIZE = 0x0100;
|
||||
UND_STACK_SIZE = 0x0100;
|
||||
SVC_STACK_SIZE = 0x0100;
|
||||
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : org = 0x00000000, len = 1024k
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not change the next code
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.vectors);
|
||||
. = ALIGN(4);
|
||||
*(.init);
|
||||
. = ALIGN(4);
|
||||
*(.text);
|
||||
. = ALIGN(4);
|
||||
*(.rodata);
|
||||
. = ALIGN(4);
|
||||
*(.rodata*);
|
||||
. = ALIGN(4);
|
||||
*(.glue_7t);
|
||||
. = ALIGN(4);
|
||||
*(.glue_7);
|
||||
. = ALIGN(4);
|
||||
etext = .;
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
edata = .;
|
||||
_edata = .;
|
||||
PROVIDE (__data_end = .);
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
PROVIDE (__bss_start = .);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__bss_end = .);
|
||||
|
||||
. = ALIGN(256);
|
||||
|
||||
PROVIDE (__stack_start = .);
|
||||
|
||||
PROVIDE (__stack_fiq_start = .);
|
||||
. += FIQ_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_fiq_end = .);
|
||||
|
||||
PROVIDE (__stack_irq_start = .);
|
||||
. += IRQ_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_irq_end = .);
|
||||
|
||||
PROVIDE (__stack_abt_start = .);
|
||||
. += ABT_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_abt_end = .);
|
||||
|
||||
PROVIDE (__stack_und_start = .);
|
||||
. += UND_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_und_end = .);
|
||||
|
||||
PROVIDE (__stack_svc_start = .);
|
||||
. += SVC_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
PROVIDE (__stack_svc_end = .);
|
||||
PROVIDE (__stack_end = .);
|
||||
PROVIDE (__heap_start = .);
|
||||
} > ram
|
||||
|
||||
}
|
||||
/*** EOF ***/
|
||||
|
|
|
|||
604
crt.s
604
crt.s
|
|
@ -1,302 +1,302 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
****************************************************************************
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 18.12.06 mifi First Version
|
||||
* The hardware initialization is based on the startup file
|
||||
* crtat91sam7x256_rom.S from NutOS 4.2.1.
|
||||
* Therefore partial copyright by egnite Software GmbH.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Some defines for the program status registers
|
||||
*/
|
||||
ARM_MODE_USER = 0x10 /* Normal User Mode */
|
||||
ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */
|
||||
ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */
|
||||
ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */
|
||||
ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */
|
||||
ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */
|
||||
ARM_MODE_SYS = 0x1F /* System Running in Privileged Operating Mode */
|
||||
ARM_MODE_MASK = 0x1F
|
||||
|
||||
I_BIT = 0x80 /* disable IRQ when I bit is set */
|
||||
F_BIT = 0x40 /* disable IRQ when I bit is set */
|
||||
|
||||
/****************************************************************************/
|
||||
/* Vector table and reset entry */
|
||||
/****************************************************************************/
|
||||
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
|
||||
_vectors:
|
||||
b ResetHandler /* Reset */
|
||||
b UndefHandler /* Undefined instruction */
|
||||
b SWIHandler /* Software interrupt */
|
||||
b PAbortHandler /* Prefetch abort */
|
||||
b DAbortHandler /* Data abort */
|
||||
b 0 /* Reserved */
|
||||
b IRQHandler /* IRQ interrupt */
|
||||
b FIQHandler /* FIQ interrupt */
|
||||
|
||||
.ltorg
|
||||
|
||||
.global ResetHandler
|
||||
.global ExitFunction
|
||||
.global absolute_to_relative
|
||||
#if USE_BREAKPOINTS
|
||||
.global DN_Packet_DCC_WaitForBP
|
||||
.global DN_Packet_DCC_ResetBPP
|
||||
.global DN_Packet_DCC_Send
|
||||
#endif
|
||||
.extern dcc_main
|
||||
.extern __stack_und_end
|
||||
|
||||
/* Variables */
|
||||
NorStartAddress1: .word 0x12345678
|
||||
NorStartAddress2: .word 0x12345678
|
||||
NorStartAddress3: .word 0x12345678
|
||||
/* Loader via H/W BP polling */
|
||||
#if USE_BREAKPOINTS
|
||||
DCC_PKT_RW_SIZE: .word 0xffffffff
|
||||
DCC_PKT_RW_DATA: .word 0xffffffff
|
||||
DCC_PKT_HW_BP: .word DN_Packet_DCC_WaitForBP
|
||||
.word 0x12345678
|
||||
#endif
|
||||
#if HAVE_LWMEM
|
||||
lwmem_init:
|
||||
.word 0x00020000
|
||||
.word 0x00060000
|
||||
lwmem_init_end:
|
||||
.word 0x00000000
|
||||
.word 0x00000000
|
||||
#endif
|
||||
/****************************************************************************/
|
||||
/* Reset handler */
|
||||
/****************************************************************************/
|
||||
ResetHandler:
|
||||
/*
|
||||
* Setup a stack for each mode
|
||||
*/
|
||||
mov r0, #0
|
||||
adr r0, _vectors
|
||||
|
||||
#ifdef SETUP_STACK_OTHERS
|
||||
msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */
|
||||
ldr sp, =__stack_und_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */
|
||||
ldr sp, =__stack_abt_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */
|
||||
ldr sp, =__stack_fiq_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */
|
||||
ldr sp, =__stack_irq_end
|
||||
add sp, r0
|
||||
#endif
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */
|
||||
ldr sp, =__stack_svc_end
|
||||
add sp, r0
|
||||
|
||||
#if USE_ICACHE \
|
||||
&& (( defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) ) \
|
||||
|| ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) ))
|
||||
mrc p15, 0, r0, cr1, cr0, 0
|
||||
orr r0, #0x1000
|
||||
mcr p15, 0, r0, cr1, cr0, 0
|
||||
#endif
|
||||
|
||||
bl plat_init
|
||||
|
||||
mov r0, #0
|
||||
adr r0, _vectors
|
||||
|
||||
#ifndef DONT_CLEAR_BSS
|
||||
/*
|
||||
* Clear .bss section
|
||||
*/
|
||||
ldr r1, =__bss_start
|
||||
ldr r2, =__bss_end
|
||||
mov r3, #0
|
||||
|
||||
add r1, r0
|
||||
add r2, r0
|
||||
bss_clear_loop:
|
||||
cmp r1, r2
|
||||
strne r3, [r1], #+4
|
||||
bne bss_clear_loop
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Jump to main
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_DCC_INTERRUPTS
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt (TODO: RIFF doesn't enable interrupt?) */
|
||||
msr cpsr, r0
|
||||
#endif
|
||||
|
||||
#if HAVE_LWMEM
|
||||
/*
|
||||
* Setup lwmem memory manager
|
||||
*/
|
||||
mov r0, #0
|
||||
adr r0, lwmem_init
|
||||
ldr r0, [r0]
|
||||
|
||||
mov r1, #0
|
||||
adr r1, _vectors
|
||||
|
||||
add r0, r1
|
||||
|
||||
mov r1, #0
|
||||
adr r1, lwmem_init
|
||||
|
||||
str r0, [r1]
|
||||
|
||||
mov r0, #0
|
||||
adr r0, lwmem_init
|
||||
bl lwmem_assignmem
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start
|
||||
*/
|
||||
mov r0, #0 /* No arguments */
|
||||
mov r1, #0 /* No arguments */
|
||||
mov r2, #0 /* No arguments */
|
||||
mov r3, #0 /* No arguments */
|
||||
|
||||
/* TOOD: Why is this line necessary */
|
||||
#if \
|
||||
( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) )
|
||||
mrc p14, 0, r0, cr0, cr5, 0
|
||||
#elif defined(CPU_XSCALE)
|
||||
mrc p14, 0, r0, cr9, cr0, 0
|
||||
#else
|
||||
mrc p14, 0, r0, cr1, cr0, 0
|
||||
#endif
|
||||
|
||||
/* Jump to Main */
|
||||
mov r0, #0
|
||||
adr r0, NorStartAddress1
|
||||
ldr r0, [r0]
|
||||
|
||||
mov r1, #0
|
||||
adr r1, NorStartAddress2
|
||||
ldr r1, [r1]
|
||||
|
||||
mov r2, #0
|
||||
adr r2, NorStartAddress3
|
||||
ldr r2, [r2]
|
||||
|
||||
b dcc_main
|
||||
|
||||
ExitFunction:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
b ExitFunction
|
||||
|
||||
/****************************************************************************/
|
||||
/* Default interrupt handler */
|
||||
/****************************************************************************/
|
||||
|
||||
UndefHandler:
|
||||
b UndefHandler
|
||||
|
||||
SWIHandler:
|
||||
b SWIHandler
|
||||
|
||||
PAbortHandler:
|
||||
b PAbortHandler
|
||||
|
||||
DAbortHandler:
|
||||
b DAbortHandler
|
||||
|
||||
IRQHandler:
|
||||
b IRQHandler
|
||||
|
||||
FIQHandler:
|
||||
b FIQHandler
|
||||
|
||||
/* PIC routines */
|
||||
absolute_to_relative:
|
||||
mov r1, #0
|
||||
adr r1, _vectors
|
||||
add r0, r1
|
||||
bx lr
|
||||
|
||||
/* Breakpoint loader routines */
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_WaitForBP:
|
||||
b DN_Packet_DCC_WaitForBP
|
||||
mov r0, #0
|
||||
adr r0, DCC_PKT_RW_DATA
|
||||
ldr r0, [r0]
|
||||
bx lr
|
||||
|
||||
DN_Packet_DCC_ResetBPP:
|
||||
mov r2, #0
|
||||
|
||||
/* Reset size */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_SIZE
|
||||
str r2, [r1]
|
||||
|
||||
/* Write offset data */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_DATA
|
||||
str r0, [r1]
|
||||
|
||||
bx lr
|
||||
|
||||
DN_Packet_DCC_Send:
|
||||
/* 01 - Data */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_DATA
|
||||
ldr r1, [r1]
|
||||
|
||||
/* 02 - Size */
|
||||
mov r2, #0
|
||||
adr r2, DCC_PKT_RW_SIZE
|
||||
ldr r2, [r2]
|
||||
|
||||
/* 03 - Writing */
|
||||
add r1, r2
|
||||
str r0, [r1]
|
||||
|
||||
/* 04 - Increment */
|
||||
mov r1, #4
|
||||
add r2, r1
|
||||
|
||||
/* 05 - Update */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_SIZE
|
||||
str r2, [r1]
|
||||
|
||||
/* 06 - End */
|
||||
mov r0, #1
|
||||
bx lr
|
||||
#endif
|
||||
|
||||
/* End */
|
||||
.weak ExitFunction
|
||||
.weak UndefHandler, PAbortHandler, DAbortHandler
|
||||
.weak IRQHandler, FIQHandler
|
||||
|
||||
.ltorg
|
||||
/*** EOF ***/
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2006 by Michael Fischer. All rights reserved.
|
||||
****************************************************************************
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 18.12.06 mifi First Version
|
||||
* The hardware initialization is based on the startup file
|
||||
* crtat91sam7x256_rom.S from NutOS 4.2.1.
|
||||
* Therefore partial copyright by egnite Software GmbH.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Some defines for the program status registers
|
||||
*/
|
||||
ARM_MODE_USER = 0x10 /* Normal User Mode */
|
||||
ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */
|
||||
ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */
|
||||
ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */
|
||||
ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */
|
||||
ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */
|
||||
ARM_MODE_SYS = 0x1F /* System Running in Privileged Operating Mode */
|
||||
ARM_MODE_MASK = 0x1F
|
||||
|
||||
I_BIT = 0x80 /* disable IRQ when I bit is set */
|
||||
F_BIT = 0x40 /* disable IRQ when I bit is set */
|
||||
|
||||
/****************************************************************************/
|
||||
/* Vector table and reset entry */
|
||||
/****************************************************************************/
|
||||
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
|
||||
_vectors:
|
||||
b ResetHandler /* Reset */
|
||||
b UndefHandler /* Undefined instruction */
|
||||
b SWIHandler /* Software interrupt */
|
||||
b PAbortHandler /* Prefetch abort */
|
||||
b DAbortHandler /* Data abort */
|
||||
b 0 /* Reserved */
|
||||
b IRQHandler /* IRQ interrupt */
|
||||
b FIQHandler /* FIQ interrupt */
|
||||
|
||||
.ltorg
|
||||
|
||||
.global ResetHandler
|
||||
.global ExitFunction
|
||||
.global absolute_to_relative
|
||||
#if USE_BREAKPOINTS
|
||||
.global DN_Packet_DCC_WaitForBP
|
||||
.global DN_Packet_DCC_ResetBPP
|
||||
.global DN_Packet_DCC_Send
|
||||
#endif
|
||||
.extern dcc_main
|
||||
.extern __stack_und_end
|
||||
|
||||
/* Variables */
|
||||
NorStartAddress1: .word 0x12345678
|
||||
NorStartAddress2: .word 0x12345678
|
||||
NorStartAddress3: .word 0x12345678
|
||||
/* Loader via H/W BP polling */
|
||||
#if USE_BREAKPOINTS
|
||||
DCC_PKT_RW_SIZE: .word 0xffffffff
|
||||
DCC_PKT_RW_DATA: .word 0xffffffff
|
||||
DCC_PKT_HW_BP: .word DN_Packet_DCC_WaitForBP
|
||||
.word 0x12345678
|
||||
#endif
|
||||
#if HAVE_LWMEM
|
||||
lwmem_init:
|
||||
.word 0x00020000
|
||||
.word 0x00060000
|
||||
lwmem_init_end:
|
||||
.word 0x00000000
|
||||
.word 0x00000000
|
||||
#endif
|
||||
/****************************************************************************/
|
||||
/* Reset handler */
|
||||
/****************************************************************************/
|
||||
ResetHandler:
|
||||
/*
|
||||
* Setup a stack for each mode
|
||||
*/
|
||||
mov r0, #0
|
||||
adr r0, _vectors
|
||||
|
||||
#ifdef SETUP_STACK_OTHERS
|
||||
msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */
|
||||
ldr sp, =__stack_und_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */
|
||||
ldr sp, =__stack_abt_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */
|
||||
ldr sp, =__stack_fiq_end
|
||||
add sp, r0
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */
|
||||
ldr sp, =__stack_irq_end
|
||||
add sp, r0
|
||||
#endif
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */
|
||||
ldr sp, =__stack_svc_end
|
||||
add sp, r0
|
||||
|
||||
#if USE_ICACHE \
|
||||
&& (( defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) ) \
|
||||
|| ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) ))
|
||||
mrc p15, 0, r0, cr1, cr0, 0
|
||||
orr r0, #0x1000
|
||||
mcr p15, 0, r0, cr1, cr0, 0
|
||||
#endif
|
||||
|
||||
bl plat_init
|
||||
|
||||
mov r0, #0
|
||||
adr r0, _vectors
|
||||
|
||||
#ifndef DONT_CLEAR_BSS
|
||||
/*
|
||||
* Clear .bss section
|
||||
*/
|
||||
ldr r1, =__bss_start
|
||||
ldr r2, =__bss_end
|
||||
mov r3, #0
|
||||
|
||||
add r1, r0
|
||||
add r2, r0
|
||||
bss_clear_loop:
|
||||
cmp r1, r2
|
||||
strne r3, [r1], #+4
|
||||
bne bss_clear_loop
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Jump to main
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_DCC_INTERRUPTS
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt (TODO: RIFF doesn't enable interrupt?) */
|
||||
msr cpsr, r0
|
||||
#endif
|
||||
|
||||
#if HAVE_LWMEM
|
||||
/*
|
||||
* Setup lwmem memory manager
|
||||
*/
|
||||
mov r0, #0
|
||||
adr r0, lwmem_init
|
||||
ldr r0, [r0]
|
||||
|
||||
mov r1, #0
|
||||
adr r1, _vectors
|
||||
|
||||
add r0, r1
|
||||
|
||||
mov r1, #0
|
||||
adr r1, lwmem_init
|
||||
|
||||
str r0, [r1]
|
||||
|
||||
mov r0, #0
|
||||
adr r0, lwmem_init
|
||||
bl lwmem_assignmem
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start
|
||||
*/
|
||||
mov r0, #0 /* No arguments */
|
||||
mov r1, #0 /* No arguments */
|
||||
mov r2, #0 /* No arguments */
|
||||
mov r3, #0 /* No arguments */
|
||||
|
||||
/* TOOD: Why is this line necessary */
|
||||
#if \
|
||||
( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) )
|
||||
mrc p14, 0, r0, cr0, cr5, 0
|
||||
#elif defined(CPU_XSCALE)
|
||||
mrc p14, 0, r0, cr9, cr0, 0
|
||||
#else
|
||||
mrc p14, 0, r0, cr1, cr0, 0
|
||||
#endif
|
||||
|
||||
/* Jump to Main */
|
||||
mov r0, #0
|
||||
adr r0, NorStartAddress1
|
||||
ldr r0, [r0]
|
||||
|
||||
mov r1, #0
|
||||
adr r1, NorStartAddress2
|
||||
ldr r1, [r1]
|
||||
|
||||
mov r2, #0
|
||||
adr r2, NorStartAddress3
|
||||
ldr r2, [r2]
|
||||
|
||||
b dcc_main
|
||||
|
||||
ExitFunction:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
b ExitFunction
|
||||
|
||||
/****************************************************************************/
|
||||
/* Default interrupt handler */
|
||||
/****************************************************************************/
|
||||
|
||||
UndefHandler:
|
||||
b UndefHandler
|
||||
|
||||
SWIHandler:
|
||||
b SWIHandler
|
||||
|
||||
PAbortHandler:
|
||||
b PAbortHandler
|
||||
|
||||
DAbortHandler:
|
||||
b DAbortHandler
|
||||
|
||||
IRQHandler:
|
||||
b IRQHandler
|
||||
|
||||
FIQHandler:
|
||||
b FIQHandler
|
||||
|
||||
/* PIC routines */
|
||||
absolute_to_relative:
|
||||
mov r1, #0
|
||||
adr r1, _vectors
|
||||
add r0, r1
|
||||
bx lr
|
||||
|
||||
/* Breakpoint loader routines */
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_WaitForBP:
|
||||
b DN_Packet_DCC_WaitForBP
|
||||
mov r0, #0
|
||||
adr r0, DCC_PKT_RW_DATA
|
||||
ldr r0, [r0]
|
||||
bx lr
|
||||
|
||||
DN_Packet_DCC_ResetBPP:
|
||||
mov r2, #0
|
||||
|
||||
/* Reset size */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_SIZE
|
||||
str r2, [r1]
|
||||
|
||||
/* Write offset data */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_DATA
|
||||
str r0, [r1]
|
||||
|
||||
bx lr
|
||||
|
||||
DN_Packet_DCC_Send:
|
||||
/* 01 - Data */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_DATA
|
||||
ldr r1, [r1]
|
||||
|
||||
/* 02 - Size */
|
||||
mov r2, #0
|
||||
adr r2, DCC_PKT_RW_SIZE
|
||||
ldr r2, [r2]
|
||||
|
||||
/* 03 - Writing */
|
||||
add r1, r2
|
||||
str r0, [r1]
|
||||
|
||||
/* 04 - Increment */
|
||||
mov r1, #4
|
||||
add r2, r1
|
||||
|
||||
/* 05 - Update */
|
||||
mov r1, #0
|
||||
adr r1, DCC_PKT_RW_SIZE
|
||||
str r2, [r1]
|
||||
|
||||
/* 06 - End */
|
||||
mov r0, #1
|
||||
bx lr
|
||||
#endif
|
||||
|
||||
/* End */
|
||||
.weak ExitFunction
|
||||
.weak UndefHandler, PAbortHandler, DAbortHandler
|
||||
.weak IRQHandler, FIQHandler
|
||||
|
||||
.ltorg
|
||||
/*** EOF ***/
|
||||
|
|
|
|||
140
dcc/bitutils.c
140
dcc/bitutils.c
|
|
@ -1,71 +1,71 @@
|
|||
#include "dcc/plat.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
/*
|
||||
* Bit Helpers
|
||||
*/
|
||||
|
||||
/* 32 */
|
||||
static uint32_t _get_bit32(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U32(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit32(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint32_t value)
|
||||
{
|
||||
WRITE_U32(offset, (READ_U32(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
uint32_t GET_BIT32(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit32(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT32(uint32_t offset, bitmask bitmask, uint32_t value)
|
||||
{
|
||||
_set_bit32(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
}
|
||||
|
||||
/* 16 */
|
||||
static uint16_t _get_bit16(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U16(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit16(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint16_t value)
|
||||
{
|
||||
WRITE_U16(offset, (READ_U16(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
|
||||
uint16_t GET_BIT16(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit16(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT16(uint32_t offset, bitmask bitmask, uint16_t value)
|
||||
{
|
||||
_set_bit16(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
}
|
||||
|
||||
|
||||
/* 8 */
|
||||
static uint8_t _get_bit8(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U8(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit8(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint8_t value)
|
||||
{
|
||||
WRITE_U8(offset, (READ_U8(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
uint8_t GET_BIT8(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit8(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT8(uint32_t offset, bitmask bitmask, uint8_t value)
|
||||
{
|
||||
_set_bit8(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
#include "dcc/plat.h"
|
||||
#include "bitutils.h"
|
||||
|
||||
/*
|
||||
* Bit Helpers
|
||||
*/
|
||||
|
||||
/* 32 */
|
||||
static uint32_t _get_bit32(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U32(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit32(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint32_t value)
|
||||
{
|
||||
WRITE_U32(offset, (READ_U32(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
uint32_t GET_BIT32(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit32(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT32(uint32_t offset, bitmask bitmask, uint32_t value)
|
||||
{
|
||||
_set_bit32(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
}
|
||||
|
||||
/* 16 */
|
||||
static uint16_t _get_bit16(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U16(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit16(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint16_t value)
|
||||
{
|
||||
WRITE_U16(offset, (READ_U16(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
|
||||
uint16_t GET_BIT16(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit16(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT16(uint32_t offset, bitmask bitmask, uint16_t value)
|
||||
{
|
||||
_set_bit16(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
}
|
||||
|
||||
|
||||
/* 8 */
|
||||
static uint8_t _get_bit8(uint32_t offset, uint32_t bit_position, uint32_t bit_mask)
|
||||
{
|
||||
return (READ_U8(offset) >> bit_position) & bit_mask;
|
||||
}
|
||||
|
||||
static void _set_bit8(uint32_t offset, uint32_t bit_position, uint32_t bit_mask, uint8_t value)
|
||||
{
|
||||
WRITE_U8(offset, (READ_U8(offset) & ~(bit_mask << bit_position)) | ((value & bit_mask) << bit_position));
|
||||
}
|
||||
|
||||
uint8_t GET_BIT8(uint32_t offset, bitmask bitmask)
|
||||
{
|
||||
return _get_bit8(offset, bitmask.bit_pos, bitmask.bit_mask);
|
||||
}
|
||||
|
||||
void SET_BIT8(uint32_t offset, bitmask bitmask, uint8_t value)
|
||||
{
|
||||
_set_bit8(offset, bitmask.bit_pos, bitmask.bit_mask, value);
|
||||
}
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIT_SET(src, bm, value) ((src & ~((bm).bit_mask << (bm).bit_pos)) | ((value & (bm).bit_mask) << (bm).bit_pos))
|
||||
#define BIT_SET_VAR(src, bm, value) (src) = BIT_SET(src, bm, value);
|
||||
|
||||
typedef struct {
|
||||
uint32_t bit_pos;
|
||||
uint32_t bit_mask;
|
||||
} bitmask;
|
||||
|
||||
uint8_t GET_BIT8(uint32_t offset, bitmask bitmask);
|
||||
uint16_t GET_BIT16(uint32_t offset, bitmask bitmask);
|
||||
uint32_t GET_BIT32(uint32_t offset, bitmask bitmask);
|
||||
|
||||
void SET_BIT8(uint32_t offset, bitmask bitmask, uint8_t value);
|
||||
void SET_BIT16(uint32_t offset, bitmask bitmask, uint16_t value);
|
||||
void SET_BIT32(uint32_t offset, bitmask bitmask, uint32_t value);
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIT_SET(src, bm, value) ((src & ~((bm).bit_mask << (bm).bit_pos)) | ((value & (bm).bit_mask) << (bm).bit_pos))
|
||||
#define BIT_SET_VAR(src, bm, value) (src) = BIT_SET(src, bm, value);
|
||||
|
||||
typedef struct {
|
||||
uint32_t bit_pos;
|
||||
uint32_t bit_mask;
|
||||
} bitmask;
|
||||
|
||||
uint8_t GET_BIT8(uint32_t offset, bitmask bitmask);
|
||||
uint16_t GET_BIT16(uint32_t offset, bitmask bitmask);
|
||||
uint32_t GET_BIT32(uint32_t offset, bitmask bitmask);
|
||||
|
||||
void SET_BIT8(uint32_t offset, bitmask bitmask, uint8_t value);
|
||||
void SET_BIT16(uint32_t offset, bitmask bitmask, uint16_t value);
|
||||
void SET_BIT32(uint32_t offset, bitmask bitmask, uint32_t value);
|
||||
|
|
|
|||
|
|
@ -1,352 +1,352 @@
|
|||
#include "dn_dcc_proto.h"
|
||||
#if HAVE_MINILZO
|
||||
#include "../minilzo/minilzo.h"
|
||||
#endif
|
||||
#if HAVE_LZ4
|
||||
#include "../lz4/lz4.h"
|
||||
#endif
|
||||
|
||||
/* 00 - Shared */
|
||||
#include <memory.h>
|
||||
#ifdef DCC_TESTING
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* 01 - Checksum */
|
||||
/* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license.
|
||||
http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c.
|
||||
or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c
|
||||
The polynomial is 0x04c11db7L. */
|
||||
const uint32_t crctab[] = {
|
||||
0x0,
|
||||
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
||||
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
||||
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
||||
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
||||
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
||||
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
||||
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
||||
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
||||
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
||||
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
||||
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
||||
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
||||
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
||||
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
||||
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
||||
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
||||
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
||||
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
||||
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
||||
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
||||
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
||||
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
||||
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
||||
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
||||
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
||||
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
||||
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
||||
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
||||
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
||||
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
||||
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
||||
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
||||
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
||||
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
|
||||
|
||||
uint32_t DN_Calculate_CRC32(uint32_t crc, uint8_t* data, uint32_t len)
|
||||
{
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
wdog_reset();
|
||||
COMPUTE(crc, data[i]);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* 02 - Compress */
|
||||
uint32_t DN_RLE_Matching(uint8_t *src, uint32_t size) {
|
||||
uint32_t offset = 0;
|
||||
uint32_t count = 1;
|
||||
|
||||
if (size < 2) return count;
|
||||
|
||||
while ((offset < (size - 1)) && (count < 0x7fff) && (src[offset] == src[offset + 1])) {
|
||||
wdog_reset();
|
||||
count++;
|
||||
offset++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t DN_Packet_Compress(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_RLE;
|
||||
uint32_t SIZE;
|
||||
uint32_t inOffset = 0;
|
||||
uint32_t outOffset = 8;
|
||||
uint16_t RLE_Count;
|
||||
uint16_t RAW_Count;
|
||||
uint32_t rawInOffset;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
while (inOffset < size) {
|
||||
wdog_reset();
|
||||
RLE_Count = DN_RLE_Matching(src + inOffset, size - inOffset);
|
||||
|
||||
if (RLE_Count == 1) {
|
||||
RAW_Count = 0;
|
||||
rawInOffset = inOffset;
|
||||
|
||||
while (RLE_Count == 1 && inOffset < size) {
|
||||
wdog_reset();
|
||||
RAW_Count++;
|
||||
inOffset++;
|
||||
|
||||
if (RAW_Count >= 0x7fff) break;
|
||||
RLE_Count = DN_RLE_Matching(src + inOffset, size - inOffset);
|
||||
}
|
||||
|
||||
memcpy(dest + outOffset, &RAW_Count, 2);
|
||||
memcpy(dest + outOffset + 2, src + rawInOffset, RAW_Count);
|
||||
outOffset += 2 + RAW_Count;
|
||||
}
|
||||
|
||||
if (RLE_Count > 1) {
|
||||
RLE_Count |= 0x8000;
|
||||
|
||||
memcpy(dest + outOffset, &RLE_Count, 2);
|
||||
dest[outOffset + 2] = src[inOffset];
|
||||
|
||||
inOffset += RLE_Count & 0x7fff;
|
||||
|
||||
outOffset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
|
||||
#if HAVE_MINILZO
|
||||
static uint8_t lzo_work_buffer[LZO1X_1_MEM_COMPRESS];
|
||||
|
||||
uint32_t DN_Packet_Compress2(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_LZO;
|
||||
uint32_t SIZE;
|
||||
uint32_t outOffset = 8;
|
||||
lzo_uint lzoSize;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
|
||||
wdog_reset();
|
||||
lzo1x_1_compress(src, size, dest + 8, &lzoSize, lzo_work_buffer);
|
||||
|
||||
wdog_reset();
|
||||
outOffset += lzoSize;
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
uint32_t DN_Packet_Compress3(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_LZ4;
|
||||
uint32_t SIZE;
|
||||
uint32_t outOffset = 8;
|
||||
uint32_t lz4_size;
|
||||
uint32_t lz4_comp_size;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
|
||||
wdog_reset();
|
||||
lz4_comp_size = LZ4_compressBound(size);
|
||||
lz4_size = LZ4_compress_default((const char *)src, (char *)(dest + 8), size, lz4_comp_size);
|
||||
|
||||
wdog_reset();
|
||||
outOffset += lz4_size;
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t DN_Packet_CompressNone(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_NONE;
|
||||
uint32_t outOffset = 4;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
memcpy(dest + 4, src, size);
|
||||
outOffset += size;
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
|
||||
/* 03 - DCC Packets */
|
||||
#ifdef DCC_TESTING
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data) {
|
||||
printf("DCC SEND: 0x%08X\n", data);
|
||||
return 1;
|
||||
};
|
||||
uint32_t DN_Packet_DCC_Read() {
|
||||
uint32_t count = 0;
|
||||
uint32_t dat_read;
|
||||
do {
|
||||
printf("DCC READ: ");
|
||||
count = scanf("%x", &dat_read);
|
||||
scanf("%*[^\n]");
|
||||
} while (count <= 0);
|
||||
return dat_read;
|
||||
};
|
||||
#elif USE_BREAKPOINTS
|
||||
static uint8_t cmdBuf[DCC_BUFFER_SIZE + 0x4000];
|
||||
static uint32_t *cmdReadBuf;
|
||||
extern uint32_t *DN_Packet_DCC_WaitForBP(void);
|
||||
extern void DN_Packet_DCC_ResetBPP(uint32_t *command_buf);
|
||||
extern uint32_t DN_Packet_DCC_Send(uint32_t data);
|
||||
uint32_t DN_Packet_DCC_Read(void) {
|
||||
return *cmdReadBuf++;
|
||||
};
|
||||
#else
|
||||
#if \
|
||||
( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) )
|
||||
#define DCC_RBIT (1 << 30)
|
||||
#define DCC_WBIT (1 << 29)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C0, C1" : "=r" (x) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C0, C5" : : "r" (x))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C0, C5" : "=r" (x) :)
|
||||
#elif defined(CPU_XSCALE)
|
||||
#define DCC_RBIT (1 << 31)
|
||||
#define DCC_WBIT (1 << 28)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C14, C0" : "=r" (dcc_reg) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C8, C0" : : "r" (data))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C9, C0" : "=r" (dcc_reg) :)
|
||||
#else
|
||||
#define DCC_RBIT (1 << 0)
|
||||
#define DCC_WBIT (1 << 1)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C0, C0" : "=r" (x) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C1, C0" : : "r" (x))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C1, C0" : "=r" (x) :)
|
||||
#endif
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data) {
|
||||
volatile uint32_t dcc_reg;
|
||||
|
||||
do {
|
||||
wdog_reset();
|
||||
DCC_GET_STATUS(dcc_reg);
|
||||
/* operation controlled by master, cancel operation
|
||||
upon reception of data for immediate response */
|
||||
#ifdef CANCEL_WRITE_ON_DCC_READ_BIT
|
||||
if (dcc_reg & DCC_RBIT) return 0; // Cancel if the debugger sends any data to the DCC buffer.
|
||||
#endif
|
||||
} while (dcc_reg & DCC_WBIT); // Wait until the debugger reads the WB data, which sets the W bit to low.
|
||||
|
||||
DCC_WRITE(data); // Then, the host writes the data to the WB bit, setting the W bit to high.
|
||||
return 1;
|
||||
};
|
||||
|
||||
uint32_t DN_Packet_DCC_Read(void) {
|
||||
volatile uint32_t dcc_reg;
|
||||
|
||||
do {
|
||||
wdog_reset();
|
||||
DCC_GET_STATUS(dcc_reg);
|
||||
} while ((dcc_reg & DCC_RBIT) == 0); // When debugger sends the data to the DCC, the R bit was set to high.
|
||||
|
||||
DCC_READ(dcc_reg); // Then, the host reads the RB data, setting the R bit to low.
|
||||
return dcc_reg;
|
||||
};
|
||||
#endif
|
||||
|
||||
void DN_Packet_Send(uint8_t *src, uint32_t size) {
|
||||
if (size & 3) return; // Must be dword aligned
|
||||
uint32_t checksum = DN_Calculate_CRC32(0xffffffff, src, size);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_ResetBPP((uint32_t *)cmdBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_DCC_Send(size >> 2);
|
||||
for (uint32_t src_offset = 0; src_offset < (size >> 2); src_offset++) {
|
||||
wdog_reset();
|
||||
DN_Packet_DCC_Send(((uint32_t *)(src))[src_offset]);
|
||||
}
|
||||
|
||||
DN_Packet_DCC_Send(checksum);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
cmdReadBuf = DN_Packet_DCC_WaitForBP();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DN_Packet_Send_One(uint32_t data) {
|
||||
uint32_t checksum = DN_Calculate_CRC32(0xffffffff, (uint8_t *)&data, 4);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_ResetBPP((uint32_t *)cmdBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_DCC_Send(1);
|
||||
DN_Packet_DCC_Send(data);
|
||||
|
||||
DN_Packet_DCC_Send(checksum);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
cmdReadBuf = DN_Packet_DCC_WaitForBP();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DN_Packet_Read(uint8_t *dest, uint32_t size) {
|
||||
if (size & 3) return; // Must be dword aligned
|
||||
|
||||
for (uint32_t dst_offset = 0; dst_offset < (size >> 2); dst_offset++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(dest))[dst_offset] = DN_Packet_DCC_Read();
|
||||
}
|
||||
}
|
||||
|
||||
/* 04 - Utilities */
|
||||
uint32_t DN_Log2(uint32_t value)
|
||||
{
|
||||
uint32_t m = 0;
|
||||
while (1) {
|
||||
if ((1 << m) >= value)
|
||||
return m;
|
||||
m++;
|
||||
}
|
||||
#include "dn_dcc_proto.h"
|
||||
#if HAVE_MINILZO
|
||||
#include "../minilzo/minilzo.h"
|
||||
#endif
|
||||
#if HAVE_LZ4
|
||||
#include "../lz4/lz4.h"
|
||||
#endif
|
||||
|
||||
/* 00 - Shared */
|
||||
#include <memory.h>
|
||||
#ifdef DCC_TESTING
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* 01 - Checksum */
|
||||
/* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license.
|
||||
http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c.
|
||||
or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c
|
||||
The polynomial is 0x04c11db7L. */
|
||||
const uint32_t crctab[] = {
|
||||
0x0,
|
||||
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
|
||||
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
|
||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
|
||||
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
|
||||
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
|
||||
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
|
||||
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
|
||||
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
|
||||
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
|
||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
|
||||
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
|
||||
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
|
||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
|
||||
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
|
||||
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
|
||||
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
|
||||
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
|
||||
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
|
||||
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
|
||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
|
||||
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
|
||||
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
|
||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
|
||||
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
|
||||
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
|
||||
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
|
||||
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
|
||||
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
|
||||
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
|
||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
|
||||
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
|
||||
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
|
||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
|
||||
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
|
||||
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
|
||||
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
|
||||
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
|
||||
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
|
||||
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
|
||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
|
||||
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
|
||||
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
|
||||
|
||||
uint32_t DN_Calculate_CRC32(uint32_t crc, uint8_t* data, uint32_t len)
|
||||
{
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
wdog_reset();
|
||||
COMPUTE(crc, data[i]);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* 02 - Compress */
|
||||
uint32_t DN_RLE_Matching(uint8_t *src, uint32_t size) {
|
||||
uint32_t offset = 0;
|
||||
uint32_t count = 1;
|
||||
|
||||
if (size < 2) return count;
|
||||
|
||||
while ((offset < (size - 1)) && (count < 0x7fff) && (src[offset] == src[offset + 1])) {
|
||||
wdog_reset();
|
||||
count++;
|
||||
offset++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t DN_Packet_Compress(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_RLE;
|
||||
uint32_t SIZE;
|
||||
uint32_t inOffset = 0;
|
||||
uint32_t outOffset = 8;
|
||||
uint16_t RLE_Count;
|
||||
uint16_t RAW_Count;
|
||||
uint32_t rawInOffset;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
while (inOffset < size) {
|
||||
wdog_reset();
|
||||
RLE_Count = DN_RLE_Matching(src + inOffset, size - inOffset);
|
||||
|
||||
if (RLE_Count == 1) {
|
||||
RAW_Count = 0;
|
||||
rawInOffset = inOffset;
|
||||
|
||||
while (RLE_Count == 1 && inOffset < size) {
|
||||
wdog_reset();
|
||||
RAW_Count++;
|
||||
inOffset++;
|
||||
|
||||
if (RAW_Count >= 0x7fff) break;
|
||||
RLE_Count = DN_RLE_Matching(src + inOffset, size - inOffset);
|
||||
}
|
||||
|
||||
memcpy(dest + outOffset, &RAW_Count, 2);
|
||||
memcpy(dest + outOffset + 2, src + rawInOffset, RAW_Count);
|
||||
outOffset += 2 + RAW_Count;
|
||||
}
|
||||
|
||||
if (RLE_Count > 1) {
|
||||
RLE_Count |= 0x8000;
|
||||
|
||||
memcpy(dest + outOffset, &RLE_Count, 2);
|
||||
dest[outOffset + 2] = src[inOffset];
|
||||
|
||||
inOffset += RLE_Count & 0x7fff;
|
||||
|
||||
outOffset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
|
||||
#if HAVE_MINILZO
|
||||
static uint8_t lzo_work_buffer[LZO1X_1_MEM_COMPRESS];
|
||||
|
||||
uint32_t DN_Packet_Compress2(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_LZO;
|
||||
uint32_t SIZE;
|
||||
uint32_t outOffset = 8;
|
||||
lzo_uint lzoSize;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
|
||||
wdog_reset();
|
||||
lzo1x_1_compress(src, size, dest + 8, &lzoSize, lzo_work_buffer);
|
||||
|
||||
wdog_reset();
|
||||
outOffset += lzoSize;
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
uint32_t DN_Packet_Compress3(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_LZ4;
|
||||
uint32_t SIZE;
|
||||
uint32_t outOffset = 8;
|
||||
uint32_t lz4_size;
|
||||
uint32_t lz4_comp_size;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
|
||||
wdog_reset();
|
||||
lz4_comp_size = LZ4_compressBound(size);
|
||||
lz4_size = LZ4_compress_default((const char *)src, (char *)(dest + 8), size, lz4_comp_size);
|
||||
|
||||
wdog_reset();
|
||||
outOffset += lz4_size;
|
||||
|
||||
SIZE = outOffset - 4;
|
||||
memcpy(dest + 4, &SIZE, 4);
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t DN_Packet_CompressNone(uint8_t *src, uint32_t size, uint8_t *dest)
|
||||
{
|
||||
uint32_t MAGIC = CMD_WRITE_COMP_NONE;
|
||||
uint32_t outOffset = 4;
|
||||
|
||||
memcpy(dest, &MAGIC, 4);
|
||||
memcpy(dest + 4, src, size);
|
||||
outOffset += size;
|
||||
|
||||
return ALIGN4(outOffset);
|
||||
}
|
||||
|
||||
/* 03 - DCC Packets */
|
||||
#ifdef DCC_TESTING
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data) {
|
||||
printf("DCC SEND: 0x%08X\n", data);
|
||||
return 1;
|
||||
};
|
||||
uint32_t DN_Packet_DCC_Read() {
|
||||
uint32_t count = 0;
|
||||
uint32_t dat_read;
|
||||
do {
|
||||
printf("DCC READ: ");
|
||||
count = scanf("%x", &dat_read);
|
||||
scanf("%*[^\n]");
|
||||
} while (count <= 0);
|
||||
return dat_read;
|
||||
};
|
||||
#elif USE_BREAKPOINTS
|
||||
static uint8_t cmdBuf[DCC_BUFFER_SIZE + 0x4000];
|
||||
static uint32_t *cmdReadBuf;
|
||||
extern uint32_t *DN_Packet_DCC_WaitForBP(void);
|
||||
extern void DN_Packet_DCC_ResetBPP(uint32_t *command_buf);
|
||||
extern uint32_t DN_Packet_DCC_Send(uint32_t data);
|
||||
uint32_t DN_Packet_DCC_Read(void) {
|
||||
return *cmdReadBuf++;
|
||||
};
|
||||
#else
|
||||
#if \
|
||||
( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) \
|
||||
|| ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_7R__) )
|
||||
#define DCC_RBIT (1 << 30)
|
||||
#define DCC_WBIT (1 << 29)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C0, C1" : "=r" (x) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C0, C5" : : "r" (x))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C0, C5" : "=r" (x) :)
|
||||
#elif defined(CPU_XSCALE)
|
||||
#define DCC_RBIT (1 << 31)
|
||||
#define DCC_WBIT (1 << 28)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C14, C0" : "=r" (dcc_reg) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C8, C0" : : "r" (data))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C9, C0" : "=r" (dcc_reg) :)
|
||||
#else
|
||||
#define DCC_RBIT (1 << 0)
|
||||
#define DCC_WBIT (1 << 1)
|
||||
|
||||
#define DCC_GET_STATUS(x) asm volatile ("mrc p14, 0, %0, C0, C0" : "=r" (x) :)
|
||||
#define DCC_WRITE(x) asm volatile ("mcr p14, 0, %0, C1, C0" : : "r" (x))
|
||||
#define DCC_READ(x) asm volatile ("mrc p14, 0, %0, C1, C0" : "=r" (x) :)
|
||||
#endif
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data) {
|
||||
volatile uint32_t dcc_reg;
|
||||
|
||||
do {
|
||||
wdog_reset();
|
||||
DCC_GET_STATUS(dcc_reg);
|
||||
/* operation controlled by master, cancel operation
|
||||
upon reception of data for immediate response */
|
||||
#ifdef CANCEL_WRITE_ON_DCC_READ_BIT
|
||||
if (dcc_reg & DCC_RBIT) return 0; // Cancel if the debugger sends any data to the DCC buffer.
|
||||
#endif
|
||||
} while (dcc_reg & DCC_WBIT); // Wait until the debugger reads the WB data, which sets the W bit to low.
|
||||
|
||||
DCC_WRITE(data); // Then, the host writes the data to the WB bit, setting the W bit to high.
|
||||
return 1;
|
||||
};
|
||||
|
||||
uint32_t DN_Packet_DCC_Read(void) {
|
||||
volatile uint32_t dcc_reg;
|
||||
|
||||
do {
|
||||
wdog_reset();
|
||||
DCC_GET_STATUS(dcc_reg);
|
||||
} while ((dcc_reg & DCC_RBIT) == 0); // When debugger sends the data to the DCC, the R bit was set to high.
|
||||
|
||||
DCC_READ(dcc_reg); // Then, the host reads the RB data, setting the R bit to low.
|
||||
return dcc_reg;
|
||||
};
|
||||
#endif
|
||||
|
||||
void DN_Packet_Send(uint8_t *src, uint32_t size) {
|
||||
if (size & 3) return; // Must be dword aligned
|
||||
uint32_t checksum = DN_Calculate_CRC32(0xffffffff, src, size);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_ResetBPP((uint32_t *)cmdBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_DCC_Send(size >> 2);
|
||||
for (uint32_t src_offset = 0; src_offset < (size >> 2); src_offset++) {
|
||||
wdog_reset();
|
||||
DN_Packet_DCC_Send(((uint32_t *)(src))[src_offset]);
|
||||
}
|
||||
|
||||
DN_Packet_DCC_Send(checksum);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
cmdReadBuf = DN_Packet_DCC_WaitForBP();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DN_Packet_Send_One(uint32_t data) {
|
||||
uint32_t checksum = DN_Calculate_CRC32(0xffffffff, (uint8_t *)&data, 4);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
DN_Packet_DCC_ResetBPP((uint32_t *)cmdBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_DCC_Send(1);
|
||||
DN_Packet_DCC_Send(data);
|
||||
|
||||
DN_Packet_DCC_Send(checksum);
|
||||
|
||||
#if USE_BREAKPOINTS
|
||||
cmdReadBuf = DN_Packet_DCC_WaitForBP();
|
||||
#endif
|
||||
}
|
||||
|
||||
void DN_Packet_Read(uint8_t *dest, uint32_t size) {
|
||||
if (size & 3) return; // Must be dword aligned
|
||||
|
||||
for (uint32_t dst_offset = 0; dst_offset < (size >> 2); dst_offset++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(dest))[dst_offset] = DN_Packet_DCC_Read();
|
||||
}
|
||||
}
|
||||
|
||||
/* 04 - Utilities */
|
||||
uint32_t DN_Log2(uint32_t value)
|
||||
{
|
||||
uint32_t m = 0;
|
||||
while (1) {
|
||||
if ((1 << m) >= value)
|
||||
return m;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,137 +1,137 @@
|
|||
#pragma once
|
||||
#include "plat.h"
|
||||
|
||||
#define DCC_BUFFER_SIZE 0x40000
|
||||
#define ALIGN2(x) ((x + 1) & ~1)
|
||||
#define ALIGN4(x) ((x + 3) & ~3)
|
||||
|
||||
typedef uint32_t DCC_RETURN;
|
||||
|
||||
typedef enum {
|
||||
MEMTYPE_NONE,
|
||||
MEMTYPE_NAND,
|
||||
MEMTYPE_NOR,
|
||||
MEMTYPE_ONENAND,
|
||||
MEMTYPE_SUPERAND,
|
||||
MEMTYPE_AND,
|
||||
MEMTYPE_AG_AND,
|
||||
} MemTypes;
|
||||
|
||||
typedef struct {
|
||||
uint8_t manufacturer;
|
||||
uint16_t device_id;
|
||||
uint8_t bit_width;
|
||||
uint32_t page_size;
|
||||
uint32_t block_size;
|
||||
uint32_t size;
|
||||
uint32_t nor_cmd_set;
|
||||
uint32_t base_offset;
|
||||
MemTypes type;
|
||||
} DCCMemory;
|
||||
|
||||
typedef struct {
|
||||
DCC_RETURN (*initialize)(DCCMemory *mem, uint32_t offset);
|
||||
DCC_RETURN (*read)(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size);
|
||||
} Driver;
|
||||
|
||||
typedef struct {
|
||||
Driver *driver;
|
||||
uint32_t base_offset;
|
||||
} Device;
|
||||
|
||||
// RIFF DCC Commands
|
||||
// Read Command: 52 01 00 00 00 00 8E 05 00 00 02 00
|
||||
// Returns: 01 00 00 00 (Len) (Data) if success, ff (Status code) 00 00 otherwise
|
||||
#define CMD_READ 0x52 // Read, READ_MEMORY command structure
|
||||
#define CMD_READ_COMP_RLE 0x0 // RLE
|
||||
#define CMD_READ_COMP_NONE 0x40 // Uncompressed (non-standard)
|
||||
#define CMD_READ_COMP_LZO 0x80 // LZO (non-standard)
|
||||
#define CMD_READ_COMP_LZ4 0xc0 // LZ4 (non-standard)
|
||||
#define CMD_READ_RESP_FAIL(x) (0xff | (x << 8)) // Read error response code
|
||||
|
||||
// Write Command: 46 00 01 00 00 00 8E 05 01 00 00 00 04 00 00 00 DD DD DD DD CC CC CC CC
|
||||
// Returns: Status code followed with target id
|
||||
#define CMD_WRITE 0x46 // Write, WRITE_MEMORY command structure
|
||||
#define CMD_WRITE_COMP_NONE 0x0 // Uncompressed
|
||||
#define CMD_WRITE_COMP_RLE 0x1 // RLE
|
||||
#define CMD_WRITE_COMP_LZO 0x2 // LZO (non-standard)
|
||||
#define CMD_WRITE_COMP_LZ4 0x3 // LZ4 (non-standard)
|
||||
|
||||
// Erase Command: 45 01 00 00 00 00 8E 05 00 00 02 00
|
||||
// Returns: Status code followed with target id
|
||||
#define CMD_ERASE 0x45 // Erase, READ_MEMORY command structure
|
||||
|
||||
// Configure: 43 00 08 00
|
||||
// Returns: 0x638 status code
|
||||
#define CMD_CONFIGURE 0x43
|
||||
|
||||
// Get Info command: 49 00 00 00
|
||||
// Returns: Initialization data
|
||||
#define CMD_GETINFO 0x49
|
||||
|
||||
// Get Memory Size command: 4d 00 00 00
|
||||
// Returns: Status code followed with memory size in MB
|
||||
#define CMD_GETMEMSIZE 0x4d
|
||||
|
||||
// Status code for Write/Erase
|
||||
#define CMD_WRITE_ERASE_STATUS(code, target) (code | (target << 8))
|
||||
|
||||
// RIFF DCC Probe Responses
|
||||
#define DCC_MEM_OK 0x4B4F // OK result, followed with flash ID and type
|
||||
// Memory types
|
||||
#define DCC_MEM_NONE 0xffff // Probe failure, followed with error code in Word 1
|
||||
// NAND
|
||||
#define DCC_MEM_NAND_U 0x0 // Uninitialized
|
||||
#define DCC_MEM_NAND_S 0x200 // Small page NAND (B: 0x4000)
|
||||
#define DCC_MEM_NAND_L 0x800 // Large page NAND (B: 0x20000)
|
||||
#define DCC_MEM_NAND_X 0x1000 // Extra-large page NAND (B: 0x40000)
|
||||
// Extended memory info
|
||||
// for NOR, RIFF computes size by summing all erase block regions.
|
||||
// (y + 1) * (z << 8), y representing the first uint16 value, and z representing the second uint16 value
|
||||
// also used for OneNAND, and other NAND-like devices
|
||||
#define DCC_MEM_EXTENDED_FLAG(no_spare) (0x3 | (no_spare << 3))
|
||||
#define DCC_MEM_EXTENDED(no_spare, page_size, block_size, size_mb) (DCC_MEM_EXTENDED_FLAG(no_spare) | (DN_Log2(page_size) << 8) | (DN_Log2(block_size) << 16) | (DN_Log2(size_mb) << 24))
|
||||
// used to set buffer size
|
||||
#define DCC_MEM_BUFFER(separate) (0x5 | (separate << 8))
|
||||
|
||||
// Response codes (For troubleshooting, refer to USB capture between RIFF and Loader)
|
||||
#define DCC_BAD_COMMAND(c) ((c << 8) | 0x20) // Unknown command, command code follows after an error code
|
||||
#define DCC_OK 0x21 // All OK
|
||||
#define DCC_CHECKSUM_ERROR 0x22 // Checksum failure
|
||||
#define DCC_INVALID_ARGS 0x23 // Invalid arguments
|
||||
#define DCC_ERASE_ERROR 0x24 // Erase error
|
||||
#define DCC_PROGRAM_ERROR 0x25 // Write error
|
||||
#define DCC_PROBE_ERROR 0x26 // Device probe failed
|
||||
#define DCC_ASSERT_ERROR 0x27 // Ready flag timeout
|
||||
#define DCC_READ_ERROR 0x28 // Read error
|
||||
#define DCC_W_ASSERT_ERROR 0x2A // Ready flag timeout during write
|
||||
#define DCC_E_ASSERT_ERROR 0x2B // Ready flag timeout during erase
|
||||
#define DCC_ROFS_ERROR 0x2D // Cannot write to read-only memory
|
||||
#define DCC_E_UNK_ERROR 0x2E // Unknown erase error, Please file a bug report
|
||||
#define DCC_WUPROT_TIMEOUT 0x2F // Write unprotect timeout
|
||||
#define DCC_WUPROT_ERROR 0x30 // Write unprotect failed
|
||||
#define DCC_W_UNK_ERROR 0x31 // Unknown write error, Please file a bug report
|
||||
#define DCC_UNK_ERROR 0x32 // Unknown error, may happen if the flash is not completely initialized.
|
||||
#define DCC_FLASH_NOENT 0x37 // Flash with this ID is not probed/not found
|
||||
#define DCC_WPROT_ERROR 0x3C // Read-only memory or Write/Erase routines not implemented
|
||||
#define DCC_NOMEM_ERROR 0x3D // Not enough memory
|
||||
|
||||
// Functions
|
||||
uint32_t DN_Packet_Compress(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#if HAVE_MINILZO
|
||||
uint32_t DN_Packet_Compress2(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#endif
|
||||
#if HAVE_LZ4
|
||||
uint32_t DN_Packet_Compress3(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#endif
|
||||
uint32_t DN_Packet_CompressNone(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
uint32_t DN_Calculate_CRC32(uint32_t crc, uint8_t* data, uint32_t len);
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data);
|
||||
uint32_t DN_Packet_DCC_Read(void);
|
||||
void DN_Packet_Send(uint8_t *src, uint32_t size);
|
||||
void DN_Packet_Send_One(uint32_t data);
|
||||
void DN_Packet_Read(uint8_t *dest, uint32_t size);
|
||||
uint32_t DN_Log2(uint32_t value);
|
||||
|
||||
// Watchdog
|
||||
#pragma once
|
||||
#include "plat.h"
|
||||
|
||||
#define DCC_BUFFER_SIZE 0x40000
|
||||
#define ALIGN2(x) ((x + 1) & ~1)
|
||||
#define ALIGN4(x) ((x + 3) & ~3)
|
||||
|
||||
typedef uint32_t DCC_RETURN;
|
||||
|
||||
typedef enum {
|
||||
MEMTYPE_NONE,
|
||||
MEMTYPE_NAND,
|
||||
MEMTYPE_NOR,
|
||||
MEMTYPE_ONENAND,
|
||||
MEMTYPE_SUPERAND,
|
||||
MEMTYPE_AND,
|
||||
MEMTYPE_AG_AND,
|
||||
} MemTypes;
|
||||
|
||||
typedef struct {
|
||||
uint8_t manufacturer;
|
||||
uint16_t device_id;
|
||||
uint8_t bit_width;
|
||||
uint32_t page_size;
|
||||
uint32_t block_size;
|
||||
uint32_t size;
|
||||
uint32_t nor_cmd_set;
|
||||
uint32_t base_offset;
|
||||
MemTypes type;
|
||||
} DCCMemory;
|
||||
|
||||
typedef struct {
|
||||
DCC_RETURN (*initialize)(DCCMemory *mem, uint32_t offset);
|
||||
DCC_RETURN (*read)(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size);
|
||||
} Driver;
|
||||
|
||||
typedef struct {
|
||||
Driver *driver;
|
||||
uint32_t base_offset;
|
||||
} Device;
|
||||
|
||||
// RIFF DCC Commands
|
||||
// Read Command: 52 01 00 00 00 00 8E 05 00 00 02 00
|
||||
// Returns: 01 00 00 00 (Len) (Data) if success, ff (Status code) 00 00 otherwise
|
||||
#define CMD_READ 0x52 // Read, READ_MEMORY command structure
|
||||
#define CMD_READ_COMP_RLE 0x0 // RLE
|
||||
#define CMD_READ_COMP_NONE 0x40 // Uncompressed (non-standard)
|
||||
#define CMD_READ_COMP_LZO 0x80 // LZO (non-standard)
|
||||
#define CMD_READ_COMP_LZ4 0xc0 // LZ4 (non-standard)
|
||||
#define CMD_READ_RESP_FAIL(x) (0xff | (x << 8)) // Read error response code
|
||||
|
||||
// Write Command: 46 00 01 00 00 00 8E 05 01 00 00 00 04 00 00 00 DD DD DD DD CC CC CC CC
|
||||
// Returns: Status code followed with target id
|
||||
#define CMD_WRITE 0x46 // Write, WRITE_MEMORY command structure
|
||||
#define CMD_WRITE_COMP_NONE 0x0 // Uncompressed
|
||||
#define CMD_WRITE_COMP_RLE 0x1 // RLE
|
||||
#define CMD_WRITE_COMP_LZO 0x2 // LZO (non-standard)
|
||||
#define CMD_WRITE_COMP_LZ4 0x3 // LZ4 (non-standard)
|
||||
|
||||
// Erase Command: 45 01 00 00 00 00 8E 05 00 00 02 00
|
||||
// Returns: Status code followed with target id
|
||||
#define CMD_ERASE 0x45 // Erase, READ_MEMORY command structure
|
||||
|
||||
// Configure: 43 00 08 00
|
||||
// Returns: 0x638 status code
|
||||
#define CMD_CONFIGURE 0x43
|
||||
|
||||
// Get Info command: 49 00 00 00
|
||||
// Returns: Initialization data
|
||||
#define CMD_GETINFO 0x49
|
||||
|
||||
// Get Memory Size command: 4d 00 00 00
|
||||
// Returns: Status code followed with memory size in MB
|
||||
#define CMD_GETMEMSIZE 0x4d
|
||||
|
||||
// Status code for Write/Erase
|
||||
#define CMD_WRITE_ERASE_STATUS(code, target) (code | (target << 8))
|
||||
|
||||
// RIFF DCC Probe Responses
|
||||
#define DCC_MEM_OK 0x4B4F // OK result, followed with flash ID and type
|
||||
// Memory types
|
||||
#define DCC_MEM_NONE 0xffff // Probe failure, followed with error code in Word 1
|
||||
// NAND
|
||||
#define DCC_MEM_NAND_U 0x0 // Uninitialized
|
||||
#define DCC_MEM_NAND_S 0x200 // Small page NAND (B: 0x4000)
|
||||
#define DCC_MEM_NAND_L 0x800 // Large page NAND (B: 0x20000)
|
||||
#define DCC_MEM_NAND_X 0x1000 // Extra-large page NAND (B: 0x40000)
|
||||
// Extended memory info
|
||||
// for NOR, RIFF computes size by summing all erase block regions.
|
||||
// (y + 1) * (z << 8), y representing the first uint16 value, and z representing the second uint16 value
|
||||
// also used for OneNAND, and other NAND-like devices
|
||||
#define DCC_MEM_EXTENDED_FLAG(no_spare) (0x3 | (no_spare << 3))
|
||||
#define DCC_MEM_EXTENDED(no_spare, page_size, block_size, size_mb) (DCC_MEM_EXTENDED_FLAG(no_spare) | (DN_Log2(page_size) << 8) | (DN_Log2(block_size) << 16) | (DN_Log2(size_mb) << 24))
|
||||
// used to set buffer size
|
||||
#define DCC_MEM_BUFFER(separate) (0x5 | (separate << 8))
|
||||
|
||||
// Response codes (For troubleshooting, refer to USB capture between RIFF and Loader)
|
||||
#define DCC_BAD_COMMAND(c) ((c << 8) | 0x20) // Unknown command, command code follows after an error code
|
||||
#define DCC_OK 0x21 // All OK
|
||||
#define DCC_CHECKSUM_ERROR 0x22 // Checksum failure
|
||||
#define DCC_INVALID_ARGS 0x23 // Invalid arguments
|
||||
#define DCC_ERASE_ERROR 0x24 // Erase error
|
||||
#define DCC_PROGRAM_ERROR 0x25 // Write error
|
||||
#define DCC_PROBE_ERROR 0x26 // Device probe failed
|
||||
#define DCC_ASSERT_ERROR 0x27 // Ready flag timeout
|
||||
#define DCC_READ_ERROR 0x28 // Read error
|
||||
#define DCC_W_ASSERT_ERROR 0x2A // Ready flag timeout during write
|
||||
#define DCC_E_ASSERT_ERROR 0x2B // Ready flag timeout during erase
|
||||
#define DCC_ROFS_ERROR 0x2D // Cannot write to read-only memory
|
||||
#define DCC_E_UNK_ERROR 0x2E // Unknown erase error, Please file a bug report
|
||||
#define DCC_WUPROT_TIMEOUT 0x2F // Write unprotect timeout
|
||||
#define DCC_WUPROT_ERROR 0x30 // Write unprotect failed
|
||||
#define DCC_W_UNK_ERROR 0x31 // Unknown write error, Please file a bug report
|
||||
#define DCC_UNK_ERROR 0x32 // Unknown error, may happen if the flash is not completely initialized.
|
||||
#define DCC_FLASH_NOENT 0x37 // Flash with this ID is not probed/not found
|
||||
#define DCC_WPROT_ERROR 0x3C // Read-only memory or Write/Erase routines not implemented
|
||||
#define DCC_NOMEM_ERROR 0x3D // Not enough memory
|
||||
|
||||
// Functions
|
||||
uint32_t DN_Packet_Compress(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#if HAVE_MINILZO
|
||||
uint32_t DN_Packet_Compress2(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#endif
|
||||
#if HAVE_LZ4
|
||||
uint32_t DN_Packet_Compress3(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
#endif
|
||||
uint32_t DN_Packet_CompressNone(uint8_t *src, uint32_t size, uint8_t *dest);
|
||||
uint32_t DN_Calculate_CRC32(uint32_t crc, uint8_t* data, uint32_t len);
|
||||
uint32_t DN_Packet_DCC_Send(uint32_t data);
|
||||
uint32_t DN_Packet_DCC_Read(void);
|
||||
void DN_Packet_Send(uint8_t *src, uint32_t size);
|
||||
void DN_Packet_Send_One(uint32_t data);
|
||||
void DN_Packet_Read(uint8_t *dest, uint32_t size);
|
||||
uint32_t DN_Log2(uint32_t value);
|
||||
|
||||
// Watchdog
|
||||
extern void wdog_reset(void);
|
||||
140
dcc/memory.c
140
dcc/memory.c
|
|
@ -1,71 +1,71 @@
|
|||
#include <stddef.h>
|
||||
#include "dn_dcc_proto.h"
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (len--) {
|
||||
if ((len & 0x3f) == 0x3f) wdog_reset();
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memset(void *dst, int val, size_t count)
|
||||
{
|
||||
register uint8_t *ptr = (uint8_t *)dst;
|
||||
|
||||
while (count-- > 0) {
|
||||
if ((count & 0x3f) == 0x3f) wdog_reset();
|
||||
*ptr++ = val;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t len)
|
||||
{
|
||||
/*
|
||||
* The following test makes use of unsigned arithmetic overflow to
|
||||
* more efficiently test the condition !(src <= dst && dst < str+len).
|
||||
* It also avoids the situation where the more explicit test would give
|
||||
* incorrect results were the calculation str+len to overflow (though
|
||||
* that issue is probably moot as such usage is probably undefined
|
||||
* behaviour and a bug anyway.
|
||||
*/
|
||||
if ((size_t)dst - (size_t)src >= len) {
|
||||
/* destination not in source data, so can safely use memcpy */
|
||||
return memcpy(dst, src, len);
|
||||
} else {
|
||||
/* copy backwards... */
|
||||
const char *end = dst;
|
||||
const char *s = (const char *)src + len;
|
||||
char *d = (char *)dst + len;
|
||||
while (d != end) {
|
||||
if (((size_t)d & 0x3f) == 0x3f) wdog_reset();
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t len)
|
||||
{
|
||||
const unsigned char *s = s1;
|
||||
const unsigned char *d = s2;
|
||||
unsigned char sc;
|
||||
unsigned char dc;
|
||||
|
||||
while (len--) {
|
||||
if ((len & 0x3f) == 0x3f) wdog_reset();
|
||||
sc = *s++;
|
||||
dc = *d++;
|
||||
if (sc - dc)
|
||||
return (sc - dc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#include <stddef.h>
|
||||
#include "dn_dcc_proto.h"
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (len--) {
|
||||
if ((len & 0x3f) == 0x3f) wdog_reset();
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memset(void *dst, int val, size_t count)
|
||||
{
|
||||
register uint8_t *ptr = (uint8_t *)dst;
|
||||
|
||||
while (count-- > 0) {
|
||||
if ((count & 0x3f) == 0x3f) wdog_reset();
|
||||
*ptr++ = val;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t len)
|
||||
{
|
||||
/*
|
||||
* The following test makes use of unsigned arithmetic overflow to
|
||||
* more efficiently test the condition !(src <= dst && dst < str+len).
|
||||
* It also avoids the situation where the more explicit test would give
|
||||
* incorrect results were the calculation str+len to overflow (though
|
||||
* that issue is probably moot as such usage is probably undefined
|
||||
* behaviour and a bug anyway.
|
||||
*/
|
||||
if ((size_t)dst - (size_t)src >= len) {
|
||||
/* destination not in source data, so can safely use memcpy */
|
||||
return memcpy(dst, src, len);
|
||||
} else {
|
||||
/* copy backwards... */
|
||||
const char *end = dst;
|
||||
const char *s = (const char *)src + len;
|
||||
char *d = (char *)dst + len;
|
||||
while (d != end) {
|
||||
if (((size_t)d & 0x3f) == 0x3f) wdog_reset();
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t len)
|
||||
{
|
||||
const unsigned char *s = s1;
|
||||
const unsigned char *d = s2;
|
||||
unsigned char sc;
|
||||
unsigned char dc;
|
||||
|
||||
while (len--) {
|
||||
if ((len & 0x3f) == 0x3f) wdog_reset();
|
||||
sc = *s++;
|
||||
dc = *d++;
|
||||
if (sc - dc)
|
||||
return (sc - dc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
52
dcc/plat.h
52
dcc/plat.h
|
|
@ -1,27 +1,27 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef DCC_TESTING
|
||||
extern void WRITE_U8(uint32_t reg, uint8_t val);
|
||||
extern void WRITE_U16(uint32_t reg, uint16_t val);
|
||||
extern void WRITE_U32(uint32_t reg, uint32_t val);
|
||||
|
||||
extern uint8_t READ_U8(uint32_t reg);
|
||||
extern uint16_t READ_U16(uint32_t reg);
|
||||
extern uint32_t READ_U32(uint32_t reg);
|
||||
|
||||
extern void *PLAT_MEMCPY(void *dest, const void *src, size_t n);
|
||||
#else
|
||||
#include <memory.h>
|
||||
|
||||
#define WRITE_U8(_reg, _val) (*((volatile uint8_t *)(_reg)) = (_val))
|
||||
#define WRITE_U16(_reg, _val) (*((volatile uint16_t *)(_reg)) = (_val))
|
||||
#define WRITE_U32(_reg, _val) (*((volatile uint32_t *)(_reg)) = (_val))
|
||||
|
||||
#define READ_U8(_reg) (*((volatile uint8_t *)(_reg)))
|
||||
#define READ_U16(_reg) (*((volatile uint16_t *)(_reg)))
|
||||
#define READ_U32(_reg) (*((volatile uint32_t *)(_reg)))
|
||||
|
||||
#define PLAT_MEMCPY memcpy
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef DCC_TESTING
|
||||
extern void WRITE_U8(uint32_t reg, uint8_t val);
|
||||
extern void WRITE_U16(uint32_t reg, uint16_t val);
|
||||
extern void WRITE_U32(uint32_t reg, uint32_t val);
|
||||
|
||||
extern uint8_t READ_U8(uint32_t reg);
|
||||
extern uint16_t READ_U16(uint32_t reg);
|
||||
extern uint32_t READ_U32(uint32_t reg);
|
||||
|
||||
extern void *PLAT_MEMCPY(void *dest, const void *src, size_t n);
|
||||
#else
|
||||
#include <memory.h>
|
||||
|
||||
#define WRITE_U8(_reg, _val) (*((volatile uint8_t *)(_reg)) = (_val))
|
||||
#define WRITE_U16(_reg, _val) (*((volatile uint16_t *)(_reg)) = (_val))
|
||||
#define WRITE_U32(_reg, _val) (*((volatile uint32_t *)(_reg)) = (_val))
|
||||
|
||||
#define READ_U8(_reg) (*((volatile uint8_t *)(_reg)))
|
||||
#define READ_U16(_reg) (*((volatile uint16_t *)(_reg)))
|
||||
#define READ_U32(_reg) (*((volatile uint32_t *)(_reg)))
|
||||
|
||||
#define PLAT_MEMCPY memcpy
|
||||
#endif
|
||||
444
dcc_emu.py
444
dcc_emu.py
|
|
@ -1,223 +1,223 @@
|
|||
#!/usr/bin/env python
|
||||
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
from capstone import *
|
||||
from capstone.arm import *
|
||||
|
||||
DEBUG = True
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
pass
|
||||
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
status_reg = 0b0100 << 28 # By default, the DCC loader can write, but not read
|
||||
rd_reg = 0
|
||||
wr_reg = 0
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc: Uc, address, size, user_data):
|
||||
global status_reg, wr_reg
|
||||
|
||||
try:
|
||||
#if address == 0x14001da0: uc.mem_write(0x0, b"\x01\x00\x7e\x22")
|
||||
if DEBUG:
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
print("CODE:",uc.mem_read(address, size))
|
||||
print("RSP1", hex(uc.reg_read(UC_ARM_REG_R0)))
|
||||
print("RSP2", hex(uc.reg_read(UC_ARM_REG_R1)))
|
||||
print("RSP3", hex(uc.reg_read(UC_ARM_REG_R2)))
|
||||
print("RSP4", hex(uc.reg_read(UC_ARM_REG_R3)))
|
||||
print("SP", hex(uc.reg_read(UC_ARM_REG_SP)))
|
||||
print("SP_DATA", uc.mem_read(uc.reg_read(UC_ARM_REG_SP), 0x10))
|
||||
|
||||
cs = Cs(CS_ARCH_ARM, CS_MODE_THUMB if uc.reg_read(UC_ARM_REG_CPSR) & (1 << 5) else CS_MODE_ARM)
|
||||
cs.detail = True
|
||||
|
||||
ins: CsInsn = [x for x in cs.disasm(uc.mem_read(address, size), address)][0]
|
||||
if ins.id == ARM_INS_MRC:
|
||||
if ins.operands[0].value.imm == 14:
|
||||
opc_1 = ins.operands[1].value.imm
|
||||
cp_dest = ins.operands[2].value.reg
|
||||
cr_n = ins.operands[3].value.imm
|
||||
cr_m = ins.operands[4].value.imm
|
||||
opc_2 = ins.operands[5].value.imm
|
||||
|
||||
if cr_n == 0:
|
||||
uc.reg_write(cp_dest, status_reg)
|
||||
|
||||
elif cr_n == 1:
|
||||
print("DCC HOST -> OCD", hex(rd_reg))
|
||||
uc.reg_write(cp_dest, rd_reg)
|
||||
status_reg &= ~1 # Sets the R bit to low, indicating that the host has finished processing the data.
|
||||
|
||||
uc.reg_write(UC_ARM_REG_PC, address+size) # Skip this instruction as we've already processed some DCC logic
|
||||
|
||||
elif ins.id == ARM_INS_MCR:
|
||||
if ins.operands[0].value.imm == 14:
|
||||
opc_1 = ins.operands[1].value.imm
|
||||
cp_dest = ins.operands[2].value.reg
|
||||
cr_n = ins.operands[3].value.imm
|
||||
cr_m = ins.operands[4].value.imm
|
||||
opc_2 = ins.operands[5].value.imm
|
||||
|
||||
if cr_n == 0:
|
||||
status_reg = uc.reg_read(cp_dest)
|
||||
|
||||
elif cr_n == 1:
|
||||
wr_reg = uc.reg_read(cp_dest)
|
||||
print("DCC OCD -> HOST", hex(wr_reg))
|
||||
status_reg |= 2 # Sets the W bit to high, indicating that the debugger is ready to process the data.
|
||||
|
||||
uc.reg_write(UC_ARM_REG_PC, address+size) # Skip this instruction as we've already processed some DCC logic
|
||||
|
||||
except KeyboardInterrupt:
|
||||
uc.emu_stop()
|
||||
raise
|
||||
# cp = 15
|
||||
# is64 = 0
|
||||
# sec = 0
|
||||
# crn = 1
|
||||
# crm = 0
|
||||
# opc1 = 0
|
||||
# opc2 = 0
|
||||
# val = ??
|
||||
|
||||
|
||||
|
||||
# Test ARM
|
||||
def test_arm():
|
||||
print("Emulate ARM code")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||
mu.ctl_exits_enabled(True)
|
||||
mu.ctl_set_exits([0])
|
||||
|
||||
mu.mem_map(0x00000000, 32 * 1024 * 1024)
|
||||
mu.mem_map(0x03000000, 2 * 1024 * 1024)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(0x14000000, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(0x14000000, open("build/dumpnow.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, b"\x01\x00\x7e\x22") # Infineon NOR
|
||||
#mu.mem_write(0x14000020, b"\x00\x00\x00\x00") # Infineon NOR
|
||||
#mu.mem_write(0x00000020, b"Q\0R\0Y\0\x02\0\0\0")
|
||||
#mu.mem_write(0x0000004e, (23).to_bytes(2, "little"))
|
||||
|
||||
#mu.mem_write(0x14000020, b"\0\0\0\x10")
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
def on_read(mu, access, address, size, value, data):
|
||||
#if DEBUG and address <= 0x14000000:
|
||||
if DEBUG:
|
||||
print("Read at", hex(address), size, mu.mem_read(address, size))
|
||||
|
||||
def on_write(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
if address <= 0x14000000:
|
||||
if address == 0xaaa and value == 0x98:
|
||||
mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
|
||||
elif address == 0xaaa and value == 0x90:
|
||||
mu.mem_write(0x00000000, b"\x01\x00\x7e\x22")
|
||||
|
||||
elif address == 0x0 and value == 0xf0:
|
||||
mu.mem_write(0x00000000, open("build/dumpnow.bin", "rb").read())
|
||||
# mu.reg_write(0x)
|
||||
print("Write at", hex(address), size, hex(value))
|
||||
# if value == 0x98:
|
||||
# mu.mem_write(0x0, open("cfi.bin", "rb").read())
|
||||
|
||||
# elif value == 0xf0:
|
||||
# mu.mem_write(0x0, open("RIFF_Nor_DCC_Test.bin", "rb").read())
|
||||
|
||||
# else:
|
||||
# mu.mem_write(address, value.to_bytes(size, "little"))
|
||||
|
||||
def on_error(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
print("Error at", hex(address), size, hex(value), "in", hex(mu.reg_read(UC_ARM_REG_PC)), "lr", hex(mu.reg_read(UC_ARM_REG_LR)))
|
||||
|
||||
mu.hook_add(UC_HOOK_MEM_READ, on_read)
|
||||
mu.hook_add(UC_HOOK_MEM_WRITE, on_write)
|
||||
mu.hook_add(UC_HOOK_MEM_INVALID, on_error)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(0x14000000, 0x1440000)
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_ARM_REG_R0)
|
||||
r1 = mu.reg_read(UC_ARM_REG_R1)
|
||||
print(">>> R0 = 0x%x" %r0)
|
||||
print(">>> R1 = 0x%x" %r1)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
def _dcc_read_host():
|
||||
global status_reg
|
||||
if (status_reg & 2) == 0: return 0
|
||||
|
||||
print("DBG READ")
|
||||
temp = wr_reg
|
||||
|
||||
status_reg &= ~2 # Debugger finally processed the data and set the W bit to low.
|
||||
return temp
|
||||
|
||||
def _dcc_write_host(data):
|
||||
import time
|
||||
global status_reg, rd_reg
|
||||
|
||||
while _dcc_read_status_host() & 1: time.sleep(0.1)
|
||||
|
||||
print("DBG WRTIE")
|
||||
rd_reg = data
|
||||
status_reg |= 1 # With the R bit set to high, the host was as motivated to process the data.
|
||||
|
||||
def _dcc_read_status_host():
|
||||
return status_reg
|
||||
|
||||
if __name__ == '__main__':
|
||||
import threading
|
||||
import time
|
||||
|
||||
t = threading.Thread(target=test_arm, daemon=True)
|
||||
t.start()
|
||||
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
iCount = _dcc_read_host()
|
||||
print("C:", hex(iCount))
|
||||
|
||||
for _ in range(iCount + 1):
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
print("RUN")
|
||||
_dcc_write_host(0x152 | 0x00000000)
|
||||
_dcc_write_host(0x00120000)
|
||||
_dcc_write_host(0x00000080)
|
||||
|
||||
while True:
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
while True:
|
||||
#!/usr/bin/env python
|
||||
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
from capstone import *
|
||||
from capstone.arm import *
|
||||
|
||||
DEBUG = True
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
pass
|
||||
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
status_reg = 0b0100 << 28 # By default, the DCC loader can write, but not read
|
||||
rd_reg = 0
|
||||
wr_reg = 0
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc: Uc, address, size, user_data):
|
||||
global status_reg, wr_reg
|
||||
|
||||
try:
|
||||
#if address == 0x14001da0: uc.mem_write(0x0, b"\x01\x00\x7e\x22")
|
||||
if DEBUG:
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
print("CODE:",uc.mem_read(address, size))
|
||||
print("RSP1", hex(uc.reg_read(UC_ARM_REG_R0)))
|
||||
print("RSP2", hex(uc.reg_read(UC_ARM_REG_R1)))
|
||||
print("RSP3", hex(uc.reg_read(UC_ARM_REG_R2)))
|
||||
print("RSP4", hex(uc.reg_read(UC_ARM_REG_R3)))
|
||||
print("SP", hex(uc.reg_read(UC_ARM_REG_SP)))
|
||||
print("SP_DATA", uc.mem_read(uc.reg_read(UC_ARM_REG_SP), 0x10))
|
||||
|
||||
cs = Cs(CS_ARCH_ARM, CS_MODE_THUMB if uc.reg_read(UC_ARM_REG_CPSR) & (1 << 5) else CS_MODE_ARM)
|
||||
cs.detail = True
|
||||
|
||||
ins: CsInsn = [x for x in cs.disasm(uc.mem_read(address, size), address)][0]
|
||||
if ins.id == ARM_INS_MRC:
|
||||
if ins.operands[0].value.imm == 14:
|
||||
opc_1 = ins.operands[1].value.imm
|
||||
cp_dest = ins.operands[2].value.reg
|
||||
cr_n = ins.operands[3].value.imm
|
||||
cr_m = ins.operands[4].value.imm
|
||||
opc_2 = ins.operands[5].value.imm
|
||||
|
||||
if cr_n == 0:
|
||||
uc.reg_write(cp_dest, status_reg)
|
||||
|
||||
elif cr_n == 1:
|
||||
print("DCC HOST -> OCD", hex(rd_reg))
|
||||
uc.reg_write(cp_dest, rd_reg)
|
||||
status_reg &= ~1 # Sets the R bit to low, indicating that the host has finished processing the data.
|
||||
|
||||
uc.reg_write(UC_ARM_REG_PC, address+size) # Skip this instruction as we've already processed some DCC logic
|
||||
|
||||
elif ins.id == ARM_INS_MCR:
|
||||
if ins.operands[0].value.imm == 14:
|
||||
opc_1 = ins.operands[1].value.imm
|
||||
cp_dest = ins.operands[2].value.reg
|
||||
cr_n = ins.operands[3].value.imm
|
||||
cr_m = ins.operands[4].value.imm
|
||||
opc_2 = ins.operands[5].value.imm
|
||||
|
||||
if cr_n == 0:
|
||||
status_reg = uc.reg_read(cp_dest)
|
||||
|
||||
elif cr_n == 1:
|
||||
wr_reg = uc.reg_read(cp_dest)
|
||||
print("DCC OCD -> HOST", hex(wr_reg))
|
||||
status_reg |= 2 # Sets the W bit to high, indicating that the debugger is ready to process the data.
|
||||
|
||||
uc.reg_write(UC_ARM_REG_PC, address+size) # Skip this instruction as we've already processed some DCC logic
|
||||
|
||||
except KeyboardInterrupt:
|
||||
uc.emu_stop()
|
||||
raise
|
||||
# cp = 15
|
||||
# is64 = 0
|
||||
# sec = 0
|
||||
# crn = 1
|
||||
# crm = 0
|
||||
# opc1 = 0
|
||||
# opc2 = 0
|
||||
# val = ??
|
||||
|
||||
|
||||
|
||||
# Test ARM
|
||||
def test_arm():
|
||||
print("Emulate ARM code")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||
mu.ctl_exits_enabled(True)
|
||||
mu.ctl_set_exits([0])
|
||||
|
||||
mu.mem_map(0x00000000, 32 * 1024 * 1024)
|
||||
mu.mem_map(0x03000000, 2 * 1024 * 1024)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(0x14000000, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(0x14000000, open("build/dumpnow.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, b"\x01\x00\x7e\x22") # Infineon NOR
|
||||
#mu.mem_write(0x14000020, b"\x00\x00\x00\x00") # Infineon NOR
|
||||
#mu.mem_write(0x00000020, b"Q\0R\0Y\0\x02\0\0\0")
|
||||
#mu.mem_write(0x0000004e, (23).to_bytes(2, "little"))
|
||||
|
||||
#mu.mem_write(0x14000020, b"\0\0\0\x10")
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
def on_read(mu, access, address, size, value, data):
|
||||
#if DEBUG and address <= 0x14000000:
|
||||
if DEBUG:
|
||||
print("Read at", hex(address), size, mu.mem_read(address, size))
|
||||
|
||||
def on_write(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
if address <= 0x14000000:
|
||||
if address == 0xaaa and value == 0x98:
|
||||
mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
|
||||
elif address == 0xaaa and value == 0x90:
|
||||
mu.mem_write(0x00000000, b"\x01\x00\x7e\x22")
|
||||
|
||||
elif address == 0x0 and value == 0xf0:
|
||||
mu.mem_write(0x00000000, open("build/dumpnow.bin", "rb").read())
|
||||
# mu.reg_write(0x)
|
||||
print("Write at", hex(address), size, hex(value))
|
||||
# if value == 0x98:
|
||||
# mu.mem_write(0x0, open("cfi.bin", "rb").read())
|
||||
|
||||
# elif value == 0xf0:
|
||||
# mu.mem_write(0x0, open("RIFF_Nor_DCC_Test.bin", "rb").read())
|
||||
|
||||
# else:
|
||||
# mu.mem_write(address, value.to_bytes(size, "little"))
|
||||
|
||||
def on_error(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
print("Error at", hex(address), size, hex(value), "in", hex(mu.reg_read(UC_ARM_REG_PC)), "lr", hex(mu.reg_read(UC_ARM_REG_LR)))
|
||||
|
||||
mu.hook_add(UC_HOOK_MEM_READ, on_read)
|
||||
mu.hook_add(UC_HOOK_MEM_WRITE, on_write)
|
||||
mu.hook_add(UC_HOOK_MEM_INVALID, on_error)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(0x14000000, 0x1440000)
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_ARM_REG_R0)
|
||||
r1 = mu.reg_read(UC_ARM_REG_R1)
|
||||
print(">>> R0 = 0x%x" %r0)
|
||||
print(">>> R1 = 0x%x" %r1)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
def _dcc_read_host():
|
||||
global status_reg
|
||||
if (status_reg & 2) == 0: return 0
|
||||
|
||||
print("DBG READ")
|
||||
temp = wr_reg
|
||||
|
||||
status_reg &= ~2 # Debugger finally processed the data and set the W bit to low.
|
||||
return temp
|
||||
|
||||
def _dcc_write_host(data):
|
||||
import time
|
||||
global status_reg, rd_reg
|
||||
|
||||
while _dcc_read_status_host() & 1: time.sleep(0.1)
|
||||
|
||||
print("DBG WRTIE")
|
||||
rd_reg = data
|
||||
status_reg |= 1 # With the R bit set to high, the host was as motivated to process the data.
|
||||
|
||||
def _dcc_read_status_host():
|
||||
return status_reg
|
||||
|
||||
if __name__ == '__main__':
|
||||
import threading
|
||||
import time
|
||||
|
||||
t = threading.Thread(target=test_arm, daemon=True)
|
||||
t.start()
|
||||
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
iCount = _dcc_read_host()
|
||||
print("C:", hex(iCount))
|
||||
|
||||
for _ in range(iCount + 1):
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
print("RUN")
|
||||
_dcc_write_host(0x152 | 0x00000000)
|
||||
_dcc_write_host(0x00120000)
|
||||
_dcc_write_host(0x00000080)
|
||||
|
||||
while True:
|
||||
while (_dcc_read_status_host() & 2) == 0: time.sleep(0.1)
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
while True:
|
||||
time.sleep(2)
|
||||
376
dcc_emu_bp.py
376
dcc_emu_bp.py
|
|
@ -1,189 +1,189 @@
|
|||
#!/usr/bin/env python
|
||||
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
import time
|
||||
import struct
|
||||
|
||||
DEBUG = True
|
||||
|
||||
bp_offset = 0
|
||||
WAIT_RESPONSE = False
|
||||
data_rd = b""
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
pass
|
||||
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc: Uc, address, size, user_data):
|
||||
global status_reg, wr_reg, WAIT_RESPONSE, data_rd
|
||||
|
||||
try:
|
||||
#if address == 0x14001da0: uc.mem_write(0x0, b"\x01\x00\x7e\x22")
|
||||
if DEBUG:
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
print("CODE:",uc.mem_read(address, size))
|
||||
print("RSP1", hex(uc.reg_read(UC_ARM_REG_R0)))
|
||||
print("RSP2", hex(uc.reg_read(UC_ARM_REG_R1)))
|
||||
print("RSP3", hex(uc.reg_read(UC_ARM_REG_R2)))
|
||||
print("RSP4", hex(uc.reg_read(UC_ARM_REG_R3)))
|
||||
print("SP", hex(uc.reg_read(UC_ARM_REG_SP)))
|
||||
print("SP_DATA", uc.mem_read(uc.reg_read(UC_ARM_REG_SP), 0x10))
|
||||
|
||||
if address == 0x14000000 + bp_offset:
|
||||
WAIT_RESPONSE = True
|
||||
|
||||
m_size, m_start = struct.unpack("<LL", uc.mem_read(0x1400002c, 8))
|
||||
data_rd = bytes(uc.mem_read(m_start, m_size))
|
||||
|
||||
while WAIT_RESPONSE:
|
||||
time.sleep(1)
|
||||
|
||||
uc.mem_write(m_start, data_rd)
|
||||
uc.reg_write(UC_ARM_REG_PC, address + 4)
|
||||
return
|
||||
|
||||
except KeyboardInterrupt:
|
||||
uc.emu_stop()
|
||||
raise
|
||||
# cp = 15
|
||||
# is64 = 0
|
||||
# sec = 0
|
||||
# crn = 1
|
||||
# crm = 0
|
||||
# opc1 = 0
|
||||
# opc2 = 0
|
||||
# val = ??
|
||||
|
||||
# Test ARM
|
||||
def test_arm():
|
||||
global bp_offset
|
||||
|
||||
print("Emulate ARM code")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||
mu.ctl_exits_enabled(True)
|
||||
mu.ctl_set_exits([0])
|
||||
|
||||
mu.mem_map(0x00000000, 32 * 1024 * 1024)
|
||||
mu.mem_map(0x03000000, 2 * 1024 * 1024)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(0x14000000, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(0x14000000, open("build/dumpnow.bin", "rb").read())
|
||||
bp_offset = int.from_bytes(mu.mem_read(0x14000034, 4), "little")
|
||||
#mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, b"\x01\x00\x7e\x22") # Infineon NOR
|
||||
#mu.mem_write(0x14000020, b"\x00\x00\x00\x00") # Infineon NOR
|
||||
#mu.mem_write(0x00000020, b"Q\0R\0Y\0\x02\0\0\0")
|
||||
#mu.mem_write(0x0000004e, (23).to_bytes(2, "little"))
|
||||
|
||||
#mu.mem_write(0x14000020, b"\0\0\0\x10")
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
def on_read(mu, access, address, size, value, data):
|
||||
#if DEBUG and address <= 0x14000000:
|
||||
if DEBUG:
|
||||
print("Read at", hex(address), size, mu.mem_read(address, size))
|
||||
|
||||
def on_write(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
if address <= 0x14000000:
|
||||
if address == 0xaaa and value == 0x98:
|
||||
mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
|
||||
elif address == 0xaaa and value == 0x90:
|
||||
mu.mem_write(0x00000000, b"\x01\x00\x7e\x22")
|
||||
|
||||
elif address == 0x0 and value == 0xf0:
|
||||
mu.mem_write(0x00000000, open("build/dumpnow.bin", "rb").read())
|
||||
# mu.reg_write(0x)
|
||||
print("Write at", hex(address), size, hex(value))
|
||||
# if value == 0x98:
|
||||
# mu.mem_write(0x0, open("cfi.bin", "rb").read())
|
||||
|
||||
# elif value == 0xf0:
|
||||
# mu.mem_write(0x0, open("RIFF_Nor_DCC_Test.bin", "rb").read())
|
||||
|
||||
# else:
|
||||
# mu.mem_write(address, value.to_bytes(size, "little"))
|
||||
|
||||
def on_error(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
print("Error at", hex(address), size, hex(value), "in", hex(mu.reg_read(UC_ARM_REG_PC)), "lr", hex(mu.reg_read(UC_ARM_REG_LR)))
|
||||
|
||||
mu.hook_add(UC_HOOK_MEM_READ, on_read)
|
||||
mu.hook_add(UC_HOOK_MEM_WRITE, on_write)
|
||||
mu.hook_add(UC_HOOK_MEM_INVALID, on_error)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(0x14000000, 0x1440000)
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_ARM_REG_R0)
|
||||
r1 = mu.reg_read(UC_ARM_REG_R1)
|
||||
print(">>> R0 = 0x%x" %r0)
|
||||
print(">>> R1 = 0x%x" %r1)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
def _dcc_read_host():
|
||||
global data_rd
|
||||
while not WAIT_RESPONSE:
|
||||
time.sleep(0.1)
|
||||
|
||||
temp = data_rd[:4]
|
||||
data_rd = data_rd[4:]
|
||||
|
||||
return int.from_bytes(temp, "little")
|
||||
|
||||
def _dcc_write_host(data):
|
||||
global data_rd
|
||||
assert WAIT_RESPONSE, "cannot do that while running!"
|
||||
data_rd += data.to_bytes(4, "little")
|
||||
|
||||
if __name__ == '__main__':
|
||||
import threading
|
||||
import time
|
||||
|
||||
t = threading.Thread(target=test_arm, daemon=True)
|
||||
t.start()
|
||||
|
||||
iCount = _dcc_read_host()
|
||||
print("C:", hex(iCount))
|
||||
|
||||
for _ in range(iCount + 1):
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
data_rd = b""
|
||||
print("RUN")
|
||||
_dcc_write_host(0x152 | 0x00000000)
|
||||
_dcc_write_host(0x00120000)
|
||||
_dcc_write_host(0x00000080)
|
||||
|
||||
WAIT_RESPONSE = False
|
||||
while len(data_rd) > 0:
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
# while True:
|
||||
#!/usr/bin/env python
|
||||
# Sample code for ARM of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
# Python sample ported by Loi Anh Tuan <loianhtuan@gmail.com>
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.arm_const import *
|
||||
import time
|
||||
import struct
|
||||
|
||||
DEBUG = True
|
||||
|
||||
bp_offset = 0
|
||||
WAIT_RESPONSE = False
|
||||
data_rd = b""
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
pass
|
||||
#print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc: Uc, address, size, user_data):
|
||||
global status_reg, wr_reg, WAIT_RESPONSE, data_rd
|
||||
|
||||
try:
|
||||
#if address == 0x14001da0: uc.mem_write(0x0, b"\x01\x00\x7e\x22")
|
||||
if DEBUG:
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
print("CODE:",uc.mem_read(address, size))
|
||||
print("RSP1", hex(uc.reg_read(UC_ARM_REG_R0)))
|
||||
print("RSP2", hex(uc.reg_read(UC_ARM_REG_R1)))
|
||||
print("RSP3", hex(uc.reg_read(UC_ARM_REG_R2)))
|
||||
print("RSP4", hex(uc.reg_read(UC_ARM_REG_R3)))
|
||||
print("SP", hex(uc.reg_read(UC_ARM_REG_SP)))
|
||||
print("SP_DATA", uc.mem_read(uc.reg_read(UC_ARM_REG_SP), 0x10))
|
||||
|
||||
if address == 0x14000000 + bp_offset:
|
||||
WAIT_RESPONSE = True
|
||||
|
||||
m_size, m_start = struct.unpack("<LL", uc.mem_read(0x1400002c, 8))
|
||||
data_rd = bytes(uc.mem_read(m_start, m_size))
|
||||
|
||||
while WAIT_RESPONSE:
|
||||
time.sleep(1)
|
||||
|
||||
uc.mem_write(m_start, data_rd)
|
||||
uc.reg_write(UC_ARM_REG_PC, address + 4)
|
||||
return
|
||||
|
||||
except KeyboardInterrupt:
|
||||
uc.emu_stop()
|
||||
raise
|
||||
# cp = 15
|
||||
# is64 = 0
|
||||
# sec = 0
|
||||
# crn = 1
|
||||
# crm = 0
|
||||
# opc1 = 0
|
||||
# opc2 = 0
|
||||
# val = ??
|
||||
|
||||
# Test ARM
|
||||
def test_arm():
|
||||
global bp_offset
|
||||
|
||||
print("Emulate ARM code")
|
||||
try:
|
||||
# Initialize emulator in ARM mode
|
||||
mu = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||
mu.ctl_exits_enabled(True)
|
||||
mu.ctl_set_exits([0])
|
||||
|
||||
mu.mem_map(0x00000000, 32 * 1024 * 1024)
|
||||
mu.mem_map(0x03000000, 2 * 1024 * 1024)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(0x14000000, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(0x14000000, open("build/dumpnow.bin", "rb").read())
|
||||
bp_offset = int.from_bytes(mu.mem_read(0x14000034, 4), "little")
|
||||
#mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
#mu.mem_write(0x00000000, b"\x01\x00\x7e\x22") # Infineon NOR
|
||||
#mu.mem_write(0x14000020, b"\x00\x00\x00\x00") # Infineon NOR
|
||||
#mu.mem_write(0x00000020, b"Q\0R\0Y\0\x02\0\0\0")
|
||||
#mu.mem_write(0x0000004e, (23).to_bytes(2, "little"))
|
||||
|
||||
#mu.mem_write(0x14000020, b"\0\0\0\x10")
|
||||
|
||||
# initialize machine registers
|
||||
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
def on_read(mu, access, address, size, value, data):
|
||||
#if DEBUG and address <= 0x14000000:
|
||||
if DEBUG:
|
||||
print("Read at", hex(address), size, mu.mem_read(address, size))
|
||||
|
||||
def on_write(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
if address <= 0x14000000:
|
||||
if address == 0xaaa and value == 0x98:
|
||||
mu.mem_write(0x00000000, open("cfi_32mb.bin", "rb").read())
|
||||
|
||||
elif address == 0xaaa and value == 0x90:
|
||||
mu.mem_write(0x00000000, b"\x01\x00\x7e\x22")
|
||||
|
||||
elif address == 0x0 and value == 0xf0:
|
||||
mu.mem_write(0x00000000, open("build/dumpnow.bin", "rb").read())
|
||||
# mu.reg_write(0x)
|
||||
print("Write at", hex(address), size, hex(value))
|
||||
# if value == 0x98:
|
||||
# mu.mem_write(0x0, open("cfi.bin", "rb").read())
|
||||
|
||||
# elif value == 0xf0:
|
||||
# mu.mem_write(0x0, open("RIFF_Nor_DCC_Test.bin", "rb").read())
|
||||
|
||||
# else:
|
||||
# mu.mem_write(address, value.to_bytes(size, "little"))
|
||||
|
||||
def on_error(mu, access, address, size, value, data):
|
||||
if DEBUG:
|
||||
print("Error at", hex(address), size, hex(value), "in", hex(mu.reg_read(UC_ARM_REG_PC)), "lr", hex(mu.reg_read(UC_ARM_REG_LR)))
|
||||
|
||||
mu.hook_add(UC_HOOK_MEM_READ, on_read)
|
||||
mu.hook_add(UC_HOOK_MEM_WRITE, on_write)
|
||||
mu.hook_add(UC_HOOK_MEM_INVALID, on_error)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(0x14000000, 0x1440000)
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_ARM_REG_R0)
|
||||
r1 = mu.reg_read(UC_ARM_REG_R1)
|
||||
print(">>> R0 = 0x%x" %r0)
|
||||
print(">>> R1 = 0x%x" %r1)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
def _dcc_read_host():
|
||||
global data_rd
|
||||
while not WAIT_RESPONSE:
|
||||
time.sleep(0.1)
|
||||
|
||||
temp = data_rd[:4]
|
||||
data_rd = data_rd[4:]
|
||||
|
||||
return int.from_bytes(temp, "little")
|
||||
|
||||
def _dcc_write_host(data):
|
||||
global data_rd
|
||||
assert WAIT_RESPONSE, "cannot do that while running!"
|
||||
data_rd += data.to_bytes(4, "little")
|
||||
|
||||
if __name__ == '__main__':
|
||||
import threading
|
||||
import time
|
||||
|
||||
t = threading.Thread(target=test_arm, daemon=True)
|
||||
t.start()
|
||||
|
||||
iCount = _dcc_read_host()
|
||||
print("C:", hex(iCount))
|
||||
|
||||
for _ in range(iCount + 1):
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
data_rd = b""
|
||||
print("RUN")
|
||||
_dcc_write_host(0x152 | 0x00000000)
|
||||
_dcc_write_host(0x00120000)
|
||||
_dcc_write_host(0x00000080)
|
||||
|
||||
WAIT_RESPONSE = False
|
||||
while len(data_rd) > 0:
|
||||
print("H:", hex(_dcc_read_host()))
|
||||
|
||||
# while True:
|
||||
# time.sleep(2)
|
||||
24
devices.h
24
devices.h
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "flash/cfi/cfi.h"
|
||||
#include "flash/nand/nand.h"
|
||||
#include "flash/onenand/onenand.h"
|
||||
#include "flash/superand/superand.h"
|
||||
|
||||
static Device devices[] = {
|
||||
{&nor_cfi_controller, 0x0},
|
||||
// {&nand_controller, 0x0},
|
||||
{0x0, 0x0}
|
||||
#pragma once
|
||||
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "flash/cfi/cfi.h"
|
||||
#include "flash/nand/nand.h"
|
||||
#include "flash/onenand/onenand.h"
|
||||
#include "flash/superand/superand.h"
|
||||
|
||||
static Device devices[] = {
|
||||
{&nor_cfi_controller, 0x0},
|
||||
// {&nand_controller, 0x0},
|
||||
{0x0, 0x0}
|
||||
};
|
||||
282
flash/cfi/cfi.c
282
flash/cfi/cfi.c
|
|
@ -1,142 +1,142 @@
|
|||
// CFI compliant NOR Memory interface
|
||||
|
||||
#include "cfi.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#define CFI_READ(o, x) READ_U16(o + ((x) * 2))
|
||||
#define CFI_WRITE(o, x, y) WRITE_U16(o + ((x) * 2), y)
|
||||
|
||||
typedef struct {
|
||||
uint8_t bit_width;
|
||||
uint32_t block_size;
|
||||
uint32_t size;
|
||||
} CFIQuery;
|
||||
|
||||
DCC_RETURN CFI_Query(uint32_t offset, uint32_t type, CFIQuery *qry) {
|
||||
/* Check if CFI is supported*/
|
||||
if (type == 2) {
|
||||
CFI_WRITE(offset, 0x555, 0x98); // S29WS-N/S29PL-N
|
||||
if ((CFI_READ(offset, 0x10) != 0x51) || (CFI_READ(offset, 0x11) != 0x52) || (CFI_READ(offset, 0x12) != 0x59)) {
|
||||
CFI_WRITE(offset, 0x55, 0x98); // S29GL-N
|
||||
}
|
||||
} else {
|
||||
CFI_WRITE(offset, 0, 0x98);
|
||||
}
|
||||
|
||||
/* Early Sharp LRS/Renesas M6M doesn't have CFI, so bail that while we find a suitable size using ID. */
|
||||
if ((CFI_READ(offset, 0x10) != 0x51) || (CFI_READ(offset, 0x11) != 0x52) || (CFI_READ(offset, 0x12) != 0x59))
|
||||
return DCC_PROBE_ERROR;
|
||||
|
||||
if (CFI_READ(offset, 0x13) != type) // Check for valid types
|
||||
return DCC_PROBE_ERROR;
|
||||
|
||||
qry->bit_width = 16;
|
||||
qry->size = 1 << CFI_READ(offset, 0x27);
|
||||
qry->block_size = 0;
|
||||
|
||||
/* Compute block size via Erase region */
|
||||
uint16_t qry_erase_size = CFI_READ(offset, 0x2c);
|
||||
for (uint16_t i = 0; i < qry_erase_size; i++) {
|
||||
// uint16_t y = CFI_READ(offset, 0x2d + (4 * i)) | (CFI_READ(offset, 0x2e + (4 * i)) << 8);
|
||||
uint16_t z = CFI_READ(offset, 0x2f + (4 * i)) | (CFI_READ(offset, 0x30 + (4 * i)) << 8);
|
||||
|
||||
if (qry->block_size < (z << 8)) {
|
||||
qry->block_size = (z << 8);
|
||||
}
|
||||
|
||||
// qry->size += (y + 1) * (z << 8);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN CFI_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
uint32_t CFI_Type;
|
||||
CFIQuery qry = { 0 };
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
// 01 - CFI Query
|
||||
for (CFI_Type = 1; CFI_Type < 4; CFI_Type++) {
|
||||
CFI_WRITE(offset, 0, 0xff);
|
||||
CFI_WRITE(offset, 0, 0xf0);
|
||||
|
||||
ret_code = CFI_Query(offset, CFI_Type, &qry);
|
||||
if (ret_code == DCC_OK) break;
|
||||
}
|
||||
|
||||
if (CFI_Type == 4) {
|
||||
#ifdef FAIL_ON_NON_CFI
|
||||
return DCC_PROBE_ERROR;
|
||||
#else
|
||||
qry.bit_width = 16;
|
||||
qry.size = 0x02000000;
|
||||
qry.block_size = 0x10000;
|
||||
CFI_Type = 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 02 - Get Manufacturer
|
||||
if (CFI_Type == 2) { // Spansion
|
||||
CFI_WRITE(offset, 0x555, 0xaa);
|
||||
CFI_WRITE(offset, 0x2aa, 0x55);
|
||||
CFI_WRITE(offset, 0x555, 0x90);
|
||||
} else { // Something else
|
||||
CFI_WRITE(offset, 0x00, 0x90);
|
||||
}
|
||||
|
||||
mem->manufacturer = (uint8_t)CFI_READ(offset, 0x00);
|
||||
mem->device_id = CFI_READ(offset, 0x01);
|
||||
uint16_t spansion_id2 = CFI_READ(offset, 0x0e);
|
||||
uint16_t spansion_id3 = CFI_READ(offset, 0x0f);
|
||||
|
||||
mem->bit_width = qry.bit_width;
|
||||
mem->size = qry.size;
|
||||
mem->page_size = 0x200;
|
||||
mem->block_size = qry.block_size;
|
||||
mem->type = MEMTYPE_NOR;
|
||||
mem->nor_cmd_set = CFI_Type;
|
||||
mem->base_offset = offset;
|
||||
|
||||
// 03 - Reset again and apply
|
||||
CFI_WRITE(offset, 0, CFI_Type == 2 ? 0xf0 : 0xff);
|
||||
|
||||
if (mem->manufacturer == 0x1c) { // Renesas flash chip
|
||||
switch (mem->device_id >> 4) {
|
||||
case 0x7: // Found in PNC DM-P100
|
||||
case 0xf: // Found in Sanyo RL-4920
|
||||
mem->size = 0x02000000;
|
||||
break;
|
||||
|
||||
case 0xc: // Found in Sanyo SCP-3100
|
||||
mem->size = 0x01000000;
|
||||
break;
|
||||
|
||||
case 0x3: // Found in Sanyo PM-8200 (Overlaps with 4MB M5M29KB331ATP)
|
||||
case 0xb: // Found in Audiovox CDM-8910
|
||||
mem->size = 0x00800000;
|
||||
break;
|
||||
|
||||
case 0x2: // Found in SCP-5150
|
||||
mem->size = 0x00400000;
|
||||
break;
|
||||
|
||||
case 0xa: // Found in SCP-5150
|
||||
case 0x6: // M6MF16S2AVP datasheet
|
||||
mem->size = 0x00200000;
|
||||
break;
|
||||
|
||||
case 0x5: // M5M29FBT800FP datasheet
|
||||
mem->size = 0x00100000;
|
||||
break;
|
||||
}
|
||||
} else if (mem->manufacturer == 0x01) { // Spansion
|
||||
if (spansion_id2 == 0x2221 && mem->size == 0x01000000) mem->size = 0x800000;
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver nor_cfi_controller = {
|
||||
.initialize = CFI_Probe,
|
||||
.read = NULL
|
||||
// CFI compliant NOR Memory interface
|
||||
|
||||
#include "cfi.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#define CFI_READ(o, x) READ_U16(o + ((x) * 2))
|
||||
#define CFI_WRITE(o, x, y) WRITE_U16(o + ((x) * 2), y)
|
||||
|
||||
typedef struct {
|
||||
uint8_t bit_width;
|
||||
uint32_t block_size;
|
||||
uint32_t size;
|
||||
} CFIQuery;
|
||||
|
||||
DCC_RETURN CFI_Query(uint32_t offset, uint32_t type, CFIQuery *qry) {
|
||||
/* Check if CFI is supported*/
|
||||
if (type == 2) {
|
||||
CFI_WRITE(offset, 0x555, 0x98); // S29WS-N/S29PL-N
|
||||
if ((CFI_READ(offset, 0x10) != 0x51) || (CFI_READ(offset, 0x11) != 0x52) || (CFI_READ(offset, 0x12) != 0x59)) {
|
||||
CFI_WRITE(offset, 0x55, 0x98); // S29GL-N
|
||||
}
|
||||
} else {
|
||||
CFI_WRITE(offset, 0, 0x98);
|
||||
}
|
||||
|
||||
/* Early Sharp LRS/Renesas M6M doesn't have CFI, so bail that while we find a suitable size using ID. */
|
||||
if ((CFI_READ(offset, 0x10) != 0x51) || (CFI_READ(offset, 0x11) != 0x52) || (CFI_READ(offset, 0x12) != 0x59))
|
||||
return DCC_PROBE_ERROR;
|
||||
|
||||
if (CFI_READ(offset, 0x13) != type) // Check for valid types
|
||||
return DCC_PROBE_ERROR;
|
||||
|
||||
qry->bit_width = 16;
|
||||
qry->size = 1 << CFI_READ(offset, 0x27);
|
||||
qry->block_size = 0;
|
||||
|
||||
/* Compute block size via Erase region */
|
||||
uint16_t qry_erase_size = CFI_READ(offset, 0x2c);
|
||||
for (uint16_t i = 0; i < qry_erase_size; i++) {
|
||||
// uint16_t y = CFI_READ(offset, 0x2d + (4 * i)) | (CFI_READ(offset, 0x2e + (4 * i)) << 8);
|
||||
uint16_t z = CFI_READ(offset, 0x2f + (4 * i)) | (CFI_READ(offset, 0x30 + (4 * i)) << 8);
|
||||
|
||||
if (qry->block_size < (z << 8)) {
|
||||
qry->block_size = (z << 8);
|
||||
}
|
||||
|
||||
// qry->size += (y + 1) * (z << 8);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN CFI_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
uint32_t CFI_Type;
|
||||
CFIQuery qry = { 0 };
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
// 01 - CFI Query
|
||||
for (CFI_Type = 1; CFI_Type < 4; CFI_Type++) {
|
||||
CFI_WRITE(offset, 0, 0xff);
|
||||
CFI_WRITE(offset, 0, 0xf0);
|
||||
|
||||
ret_code = CFI_Query(offset, CFI_Type, &qry);
|
||||
if (ret_code == DCC_OK) break;
|
||||
}
|
||||
|
||||
if (CFI_Type == 4) {
|
||||
#ifdef FAIL_ON_NON_CFI
|
||||
return DCC_PROBE_ERROR;
|
||||
#else
|
||||
qry.bit_width = 16;
|
||||
qry.size = 0x02000000;
|
||||
qry.block_size = 0x10000;
|
||||
CFI_Type = 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 02 - Get Manufacturer
|
||||
if (CFI_Type == 2) { // Spansion
|
||||
CFI_WRITE(offset, 0x555, 0xaa);
|
||||
CFI_WRITE(offset, 0x2aa, 0x55);
|
||||
CFI_WRITE(offset, 0x555, 0x90);
|
||||
} else { // Something else
|
||||
CFI_WRITE(offset, 0x00, 0x90);
|
||||
}
|
||||
|
||||
mem->manufacturer = (uint8_t)CFI_READ(offset, 0x00);
|
||||
mem->device_id = CFI_READ(offset, 0x01);
|
||||
uint16_t spansion_id2 = CFI_READ(offset, 0x0e);
|
||||
// uint16_t spansion_id3 = CFI_READ(offset, 0x0f);
|
||||
|
||||
mem->bit_width = qry.bit_width;
|
||||
mem->size = qry.size;
|
||||
mem->page_size = 0x200;
|
||||
mem->block_size = qry.block_size;
|
||||
mem->type = MEMTYPE_NOR;
|
||||
mem->nor_cmd_set = CFI_Type;
|
||||
mem->base_offset = offset;
|
||||
|
||||
// 03 - Reset again and apply
|
||||
CFI_WRITE(offset, 0, CFI_Type == 2 ? 0xf0 : 0xff);
|
||||
|
||||
if (mem->manufacturer == 0x1c) { // Renesas flash chip
|
||||
switch (mem->device_id >> 4) {
|
||||
case 0x7: // Found in PNC DM-P100
|
||||
case 0xf: // Found in Sanyo RL-4920
|
||||
mem->size = 0x02000000;
|
||||
break;
|
||||
|
||||
case 0xc: // Found in Sanyo SCP-3100
|
||||
mem->size = 0x01000000;
|
||||
break;
|
||||
|
||||
case 0x3: // Found in Sanyo PM-8200 (Overlaps with 4MB M5M29KB331ATP)
|
||||
case 0xb: // Found in Audiovox CDM-8910
|
||||
mem->size = 0x00800000;
|
||||
break;
|
||||
|
||||
case 0x2: // Found in SCP-5150
|
||||
mem->size = 0x00400000;
|
||||
break;
|
||||
|
||||
case 0xa: // Found in SCP-5150
|
||||
case 0x6: // M6MF16S2AVP datasheet
|
||||
mem->size = 0x00200000;
|
||||
break;
|
||||
|
||||
case 0x5: // M5M29FBT800FP datasheet
|
||||
mem->size = 0x00100000;
|
||||
break;
|
||||
}
|
||||
} else if (mem->manufacturer == 0x01) { // Spansion
|
||||
if ((mem->device_id & 0xff) == 0x7e && spansion_id2 == 0x2221 && mem->size == 0x01000000) mem->size = 0x800000;
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver nor_cfi_controller = {
|
||||
.initialize = CFI_Probe,
|
||||
.read = NULL
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
extern Driver nor_cfi_controller;
|
||||
|
|
@ -1,23 +1,23 @@
|
|||
// Memory dump interface
|
||||
|
||||
#include "mmap.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN Memdump_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
mem->manufacturer = MEMDUMP_MFR;
|
||||
mem->device_id = MEMDUMP_DEVID;
|
||||
mem->bit_width = 16;
|
||||
mem->block_size = 0x10000;
|
||||
mem->page_size = 0x200;
|
||||
mem->size = MEMDUMP_MAX_SIZE;
|
||||
mem->type = MEMTYPE_NOR;
|
||||
mem->nor_cmd_set = 2;
|
||||
mem->base_offset = offset;
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver memdump = {
|
||||
.initialize = Memdump_Probe,
|
||||
.read = NULL
|
||||
// Memory dump interface
|
||||
|
||||
#include "mmap.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN Memdump_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
mem->manufacturer = MEMDUMP_MFR;
|
||||
mem->device_id = MEMDUMP_DEVID;
|
||||
mem->bit_width = 16;
|
||||
mem->block_size = 0x10000;
|
||||
mem->page_size = 0x200;
|
||||
mem->size = MEMDUMP_MAX_SIZE;
|
||||
mem->type = MEMTYPE_NOR;
|
||||
mem->nor_cmd_set = 2;
|
||||
mem->base_offset = offset;
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver memdump = {
|
||||
.initialize = Memdump_Probe,
|
||||
.read = NULL
|
||||
};
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#define MEMDUMP_MFR 0x80
|
||||
#define MEMDUMP_DEVID 0xd4
|
||||
#define MEMDUMP_MAX_SIZE 0x02000000
|
||||
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#define MEMDUMP_MFR 0x80
|
||||
#define MEMDUMP_DEVID 0xd4
|
||||
#define MEMDUMP_MAX_SIZE 0x02000000
|
||||
|
||||
extern Driver memdump;
|
||||
|
|
@ -1,297 +1,297 @@
|
|||
// Broadcomm BCM21xxx NAND Controller
|
||||
// Found in Samsung GT-S7070
|
||||
#include "../controller.h"
|
||||
#include "bcm2133.h"
|
||||
|
||||
static uint8_t is_axi;
|
||||
static uint8_t axi_cmd;
|
||||
static uint8_t bit_width;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
axi_cmd = cmd;
|
||||
if (cmd == NAND_CMD_RESET) WRITE_U32(BCM_AXI_CMD_RESET, 0);
|
||||
} else {
|
||||
WRITE_U16(BCM_NAND_CMD, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
if (axi_cmd == NAND_CMD_READID) WRITE_U32(BCM_AXI_CMD_READID, addr);
|
||||
} else {
|
||||
WRITE_U16(BCM_NAND_ADDR, addr);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
if (axi_cmd == NAND_CMD_READID) {
|
||||
return bit_width == 16 ? READ_U16(BCM_AXI_READ_ID) : READ_U8(BCM_AXI_READ_ID);
|
||||
}
|
||||
return bit_width == 16 ? READ_U16(BCM_AXI_READ_BUF) : READ_U8(BCM_AXI_READ_BUF);
|
||||
} else {
|
||||
return bit_width == 16 ? READ_U16(BCM_NAND_DATA) : READ_U8(BCM_NAND_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
int wait_count = 0x40;
|
||||
do {
|
||||
if (!(READ_U8(BCM_AXI_LOCK) & 2)) break;
|
||||
wdog_reset();
|
||||
} while (wait_count--);
|
||||
do { wdog_reset(); } while (!(READ_U8(BCM_AXI_LOCK) & 2));
|
||||
} else {
|
||||
int wait_count = 0x40;
|
||||
do {
|
||||
if (!(READ_U32(BCM_NAND_STATUS) & NAND_STATUS_READY)) break;
|
||||
wdog_reset();
|
||||
} while (wait_count--);
|
||||
do { wdog_reset(); } while (!(READ_U32(BCM_NAND_STATUS) & NAND_STATUS_READY));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t inline IS_16BIT(uint32_t axi_flag) {
|
||||
uint32_t temp = READ_U32(BCM_AXI_BIT);
|
||||
|
||||
if (axi_flag != 0x90 && axi_flag != 0xb0) {
|
||||
return ((temp >> 0x19) & 1) + 1;
|
||||
} else {
|
||||
return temp & 2;
|
||||
}
|
||||
}
|
||||
|
||||
void inline NANDC_Lock(uint8_t lock) {
|
||||
if (lock) {
|
||||
WRITE_U8(BCM_AXI_LOCK, READ_U8(BCM_AXI_LOCK) | 1);
|
||||
} else {
|
||||
WRITE_U8(BCM_AXI_LOCK, READ_U8(BCM_AXI_LOCK) & ~1);
|
||||
}
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
uint32_t axi_flags = READ_U32(BCM_AXI_FLAGS) & 0xf0;
|
||||
is_axi = axi_flags == 0xf0 || axi_flags == 0xe0;
|
||||
bit_width = IS_16BIT(axi_flags) ? 16 : 8;
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088800dc, 0x10FF440D);
|
||||
WRITE_U32(0x08090018, bit_width == 16);
|
||||
WRITE_U32(0x08090014, 0x00092ae7);
|
||||
WRITE_U32(0x08090010, 0x2c00000);
|
||||
WRITE_U32(0x0809000c, 0x10);
|
||||
} else {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) | 0x80000000);
|
||||
NANDC_Lock(1);
|
||||
|
||||
if (bit_width == 16) {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) | 0x40000000);
|
||||
} else {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) & ~0x40000000);
|
||||
}
|
||||
|
||||
WRITE_U32(0x0809000c, READ_U32(0x0809000c) | 0x8000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088ce004, READ_U32(0x088ce004) | 0x80000000);
|
||||
WRITE_U32(0x088ce004, READ_U32(0x088ce004) & ~0x40000000);
|
||||
WRITE_U32(0x088ce044, READ_U32(0x088ce044) & ~0xc0000000);
|
||||
WRITE_U32(0x088ce010, READ_U32(0x088ce010) | 0x80000000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x08090404, mem->page_size > 0x200 ? 0x17 : 0x15);
|
||||
}
|
||||
|
||||
NANDC_Lock(0);
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088ce010, READ_U32(0x088ce010) & ~0x80000000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (is_axi) {
|
||||
if (mem->page_size > 0x200) {
|
||||
WRITE_U32(BCM_AXI_ADDR2, page << 16);
|
||||
WRITE_U32(BCM_AXI_ADDR2, page >> 16);
|
||||
} else {
|
||||
WRITE_U32(BCM_AXI_ADDR1, page << 8);
|
||||
WRITE_U32(BCM_AXI_ADDR2, page >> 24);
|
||||
}
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NANDC_Lock(1);
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
NANDC_Lock(0);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
// Broadcomm BCM21xxx NAND Controller
|
||||
// Found in Samsung GT-S7070
|
||||
#include "../controller.h"
|
||||
#include "bcm2133.h"
|
||||
|
||||
static uint8_t is_axi;
|
||||
static uint8_t axi_cmd;
|
||||
static uint8_t bit_width;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
axi_cmd = cmd;
|
||||
if (cmd == NAND_CMD_RESET) WRITE_U32(BCM_AXI_CMD_RESET, 0);
|
||||
} else {
|
||||
WRITE_U16(BCM_NAND_CMD, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
if (axi_cmd == NAND_CMD_READID) WRITE_U32(BCM_AXI_CMD_READID, addr);
|
||||
} else {
|
||||
WRITE_U16(BCM_NAND_ADDR, addr);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
if (axi_cmd == NAND_CMD_READID) {
|
||||
return bit_width == 16 ? READ_U16(BCM_AXI_READ_ID) : READ_U8(BCM_AXI_READ_ID);
|
||||
}
|
||||
return bit_width == 16 ? READ_U16(BCM_AXI_READ_BUF) : READ_U8(BCM_AXI_READ_BUF);
|
||||
} else {
|
||||
return bit_width == 16 ? READ_U16(BCM_NAND_DATA) : READ_U8(BCM_NAND_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
if (is_axi) {
|
||||
int wait_count = 0x40;
|
||||
do {
|
||||
if (!(READ_U8(BCM_AXI_LOCK) & 2)) break;
|
||||
wdog_reset();
|
||||
} while (wait_count--);
|
||||
do { wdog_reset(); } while (!(READ_U8(BCM_AXI_LOCK) & 2));
|
||||
} else {
|
||||
int wait_count = 0x40;
|
||||
do {
|
||||
if (!(READ_U32(BCM_NAND_STATUS) & NAND_STATUS_READY)) break;
|
||||
wdog_reset();
|
||||
} while (wait_count--);
|
||||
do { wdog_reset(); } while (!(READ_U32(BCM_NAND_STATUS) & NAND_STATUS_READY));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t inline IS_16BIT(uint32_t axi_flag) {
|
||||
uint32_t temp = READ_U32(BCM_AXI_BIT);
|
||||
|
||||
if (axi_flag != 0x90 && axi_flag != 0xb0) {
|
||||
return ((temp >> 0x19) & 1) + 1;
|
||||
} else {
|
||||
return temp & 2;
|
||||
}
|
||||
}
|
||||
|
||||
void inline NANDC_Lock(uint8_t lock) {
|
||||
if (lock) {
|
||||
WRITE_U8(BCM_AXI_LOCK, READ_U8(BCM_AXI_LOCK) | 1);
|
||||
} else {
|
||||
WRITE_U8(BCM_AXI_LOCK, READ_U8(BCM_AXI_LOCK) & ~1);
|
||||
}
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
uint32_t axi_flags = READ_U32(BCM_AXI_FLAGS) & 0xf0;
|
||||
is_axi = axi_flags == 0xf0 || axi_flags == 0xe0;
|
||||
bit_width = IS_16BIT(axi_flags) ? 16 : 8;
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088800dc, 0x10FF440D);
|
||||
WRITE_U32(0x08090018, bit_width == 16);
|
||||
WRITE_U32(0x08090014, 0x00092ae7);
|
||||
WRITE_U32(0x08090010, 0x2c00000);
|
||||
WRITE_U32(0x0809000c, 0x10);
|
||||
} else {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) | 0x80000000);
|
||||
NANDC_Lock(1);
|
||||
|
||||
if (bit_width == 16) {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) | 0x40000000);
|
||||
} else {
|
||||
WRITE_U32(0x08090018, READ_U32(0x08090018) & ~0x40000000);
|
||||
}
|
||||
|
||||
WRITE_U32(0x0809000c, READ_U32(0x0809000c) | 0x8000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088ce004, READ_U32(0x088ce004) | 0x80000000);
|
||||
WRITE_U32(0x088ce004, READ_U32(0x088ce004) & ~0x40000000);
|
||||
WRITE_U32(0x088ce044, READ_U32(0x088ce044) & ~0xc0000000);
|
||||
WRITE_U32(0x088ce010, READ_U32(0x088ce010) | 0x80000000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x08090404, mem->page_size > 0x200 ? 0x17 : 0x15);
|
||||
}
|
||||
|
||||
NANDC_Lock(0);
|
||||
|
||||
if (is_axi) {
|
||||
WRITE_U32(0x088ce010, READ_U32(0x088ce010) & ~0x80000000);
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (is_axi) {
|
||||
if (mem->page_size > 0x200) {
|
||||
WRITE_U32(BCM_AXI_ADDR2, page << 16);
|
||||
WRITE_U32(BCM_AXI_ADDR2, page >> 16);
|
||||
} else {
|
||||
WRITE_U32(BCM_AXI_ADDR1, page << 8);
|
||||
WRITE_U32(BCM_AXI_ADDR2, page >> 24);
|
||||
}
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NANDC_Lock(1);
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
NANDC_Lock(0);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
/* Standard type*/
|
||||
#define BCM_NAND_CMD 0x08000000
|
||||
#define BCM_NAND_ADDR 0x08000004
|
||||
#define BCM_NAND_DATA 0x08000008
|
||||
#define BCM_NAND_STATUS 0x08090000
|
||||
|
||||
/* AXI type */
|
||||
#define BCM_AXI_CMD_RESET 0x020007f8
|
||||
#define BCM_AXI_CMD_READID 0x02200480
|
||||
#define BCM_AXI_READ_ID 0x02080000
|
||||
#define BCM_AXI_READ_BUF 0x02298000
|
||||
#define BCM_AXI_LOCK 0x0809001c
|
||||
#define BCM_AXI_ADDR1 0x02800000
|
||||
#define BCM_AXI_ADDR2 0x02b18000
|
||||
|
||||
/* Unknown class */
|
||||
#define BCM_AXI_BIT 0x08880008
|
||||
#pragma once
|
||||
|
||||
/* Standard type*/
|
||||
#define BCM_NAND_CMD 0x08000000
|
||||
#define BCM_NAND_ADDR 0x08000004
|
||||
#define BCM_NAND_DATA 0x08000008
|
||||
#define BCM_NAND_STATUS 0x08090000
|
||||
|
||||
/* AXI type */
|
||||
#define BCM_AXI_CMD_RESET 0x020007f8
|
||||
#define BCM_AXI_CMD_READID 0x02200480
|
||||
#define BCM_AXI_READ_ID 0x02080000
|
||||
#define BCM_AXI_READ_BUF 0x02298000
|
||||
#define BCM_AXI_LOCK 0x0809001c
|
||||
#define BCM_AXI_ADDR1 0x02800000
|
||||
#define BCM_AXI_ADDR2 0x02b18000
|
||||
|
||||
/* Unknown class */
|
||||
#define BCM_AXI_BIT 0x08880008
|
||||
#define BCM_AXI_FLAGS 0x08880010
|
||||
|
|
@ -1,101 +1,101 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t dev_id;
|
||||
uint32_t page_size;
|
||||
uint32_t chip_size;
|
||||
uint32_t block_size;
|
||||
uint32_t bits;
|
||||
} nand_info;
|
||||
|
||||
static nand_info flash_ids[] = {
|
||||
{0x6e, 0x100, 0x100000, 0x1000, 8},
|
||||
{0x64, 0x100, 0x200000, 0x1000, 8},
|
||||
{0xe8, 0x100, 0x100000, 0x1000, 8},
|
||||
{0xec, 0x100, 0x100000, 0x1000, 8},
|
||||
{0xea, 0x100, 0x200000, 0x1000, 8},
|
||||
{0x6b, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xe3, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xe5, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xd6, 0x200, 0x800000, 0x2000, 8},
|
||||
{0xe6, 0x200, 0x800000, 0x2000, 8},
|
||||
{0x33, 0x200, 0x1000000, 0x4000, 8},
|
||||
{0x73, 0x200, 0x1000000, 0x4000, 8},
|
||||
{0x43, 0x200, 0x1000000, 0x4000, 16},
|
||||
{0x53, 0x200, 0x1000000, 0x4000, 16},
|
||||
{0x35, 0x200, 0x2000000, 0x4000, 8},
|
||||
{0x75, 0x200, 0x2000000, 0x4000, 8},
|
||||
{0x45, 0x200, 0x2000000, 0x4000, 16},
|
||||
{0x55, 0x200, 0x2000000, 0x4000, 16},
|
||||
{0x36, 0x200, 0x4000000, 0x4000, 8},
|
||||
{0x76, 0x200, 0x4000000, 0x4000, 8},
|
||||
{0x46, 0x200, 0x4000000, 0x4000, 16},
|
||||
{0x56, 0x200, 0x4000000, 0x4000, 16},
|
||||
{0x78, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x79, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x72, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x74, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x39, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x49, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x59, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x71, 0x200, 0x10000000, 0x4000, 8},
|
||||
{0xa2, 0x0, 0x4000000, 0x0, 8},
|
||||
{0xb2, 0x0, 0x4000000, 0x0, 16},
|
||||
{0xc2, 0x0, 0x4000000, 0x0, 16},
|
||||
{0xf2, 0x0, 0x4000000, 0x0, 8},
|
||||
{0xa1, 0x0, 0x8000000, 0x0, 8},
|
||||
{0xb1, 0x0, 0x8000000, 0x0, 16},
|
||||
{0xc1, 0x0, 0x8000000, 0x0, 16},
|
||||
{0xf1, 0x0, 0x8000000, 0x0, 8},
|
||||
{0xaa, 0x0, 0x10000000, 0x0, 8},
|
||||
{0xba, 0x0, 0x10000000, 0x0, 16},
|
||||
{0xca, 0x0, 0x10000000, 0x0, 16},
|
||||
{0xda, 0x0, 0x10000000, 0x0, 8},
|
||||
{0xac, 0x0, 0x20000000, 0x0, 8},
|
||||
{0xbc, 0x0, 0x20000000, 0x0, 16},
|
||||
{0xcc, 0x0, 0x20000000, 0x0, 16},
|
||||
{0xdc, 0x0, 0x20000000, 0x0, 8},
|
||||
{0xa3, 0x0, 0x40000000, 0x0, 8},
|
||||
{0xb3, 0x0, 0x40000000, 0x0, 16},
|
||||
{0xc3, 0x0, 0x40000000, 0x0, 16},
|
||||
{0xd3, 0x0, 0x40000000, 0x0, 8},
|
||||
{0xa5, 0x0, 0x80000000, 0x0, 8},
|
||||
{0xb5, 0x0, 0x80000000, 0x0, 16},
|
||||
{0xc5, 0x0, 0x80000000, 0x0, 16},
|
||||
{0xd5, 0x0, 0x80000000, 0x0, 8},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NAND_STATUS_FAIL = 0x01,
|
||||
NAND_STATUS_FAIL_N1 = 0x02,
|
||||
NAND_STATUS_TRUE_READY = 0x20,
|
||||
NAND_STATUS_READY = 0x40,
|
||||
NAND_STATUS_WP = 0x80,
|
||||
} NANDStatus;
|
||||
|
||||
typedef enum {
|
||||
/* Standard NAND flash commands */
|
||||
NAND_CMD_READ0 = 0x0,
|
||||
NAND_CMD_READ1 = 0x1,
|
||||
NAND_CMD_RNDOUT = 0x5,
|
||||
NAND_CMD_PAGEPROG = 0x10,
|
||||
NAND_CMD_READOOB = 0x50,
|
||||
NAND_CMD_ERASE1 = 0x60,
|
||||
NAND_CMD_STATUS = 0x70,
|
||||
NAND_CMD_STATUS_MULTI = 0x71,
|
||||
NAND_CMD_SEQIN = 0x80,
|
||||
NAND_CMD_RNDIN = 0x85,
|
||||
NAND_CMD_READID = 0x90,
|
||||
NAND_CMD_ERASE2 = 0xd0,
|
||||
NAND_CMD_RESET = 0xff,
|
||||
|
||||
/* Extended commands for large page devices */
|
||||
NAND_CMD_READSTART = 0x30,
|
||||
NAND_CMD_RNDOUTSTART = 0xE0,
|
||||
NAND_CMD_CACHEDPROG = 0x15,
|
||||
} NANDCommands;
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem);
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t dev_id;
|
||||
uint32_t page_size;
|
||||
uint32_t chip_size;
|
||||
uint32_t block_size;
|
||||
uint32_t bits;
|
||||
} nand_info;
|
||||
|
||||
static nand_info flash_ids[] = {
|
||||
{0x6e, 0x100, 0x100000, 0x1000, 8},
|
||||
{0x64, 0x100, 0x200000, 0x1000, 8},
|
||||
{0xe8, 0x100, 0x100000, 0x1000, 8},
|
||||
{0xec, 0x100, 0x100000, 0x1000, 8},
|
||||
{0xea, 0x100, 0x200000, 0x1000, 8},
|
||||
{0x6b, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xe3, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xe5, 0x200, 0x400000, 0x2000, 8},
|
||||
{0xd6, 0x200, 0x800000, 0x2000, 8},
|
||||
{0xe6, 0x200, 0x800000, 0x2000, 8},
|
||||
{0x33, 0x200, 0x1000000, 0x4000, 8},
|
||||
{0x73, 0x200, 0x1000000, 0x4000, 8},
|
||||
{0x43, 0x200, 0x1000000, 0x4000, 16},
|
||||
{0x53, 0x200, 0x1000000, 0x4000, 16},
|
||||
{0x35, 0x200, 0x2000000, 0x4000, 8},
|
||||
{0x75, 0x200, 0x2000000, 0x4000, 8},
|
||||
{0x45, 0x200, 0x2000000, 0x4000, 16},
|
||||
{0x55, 0x200, 0x2000000, 0x4000, 16},
|
||||
{0x36, 0x200, 0x4000000, 0x4000, 8},
|
||||
{0x76, 0x200, 0x4000000, 0x4000, 8},
|
||||
{0x46, 0x200, 0x4000000, 0x4000, 16},
|
||||
{0x56, 0x200, 0x4000000, 0x4000, 16},
|
||||
{0x78, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x79, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x72, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x74, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x39, 0x200, 0x8000000, 0x4000, 8},
|
||||
{0x49, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x59, 0x200, 0x8000000, 0x4000, 16},
|
||||
{0x71, 0x200, 0x10000000, 0x4000, 8},
|
||||
{0xa2, 0x0, 0x4000000, 0x0, 8},
|
||||
{0xb2, 0x0, 0x4000000, 0x0, 16},
|
||||
{0xc2, 0x0, 0x4000000, 0x0, 16},
|
||||
{0xf2, 0x0, 0x4000000, 0x0, 8},
|
||||
{0xa1, 0x0, 0x8000000, 0x0, 8},
|
||||
{0xb1, 0x0, 0x8000000, 0x0, 16},
|
||||
{0xc1, 0x0, 0x8000000, 0x0, 16},
|
||||
{0xf1, 0x0, 0x8000000, 0x0, 8},
|
||||
{0xaa, 0x0, 0x10000000, 0x0, 8},
|
||||
{0xba, 0x0, 0x10000000, 0x0, 16},
|
||||
{0xca, 0x0, 0x10000000, 0x0, 16},
|
||||
{0xda, 0x0, 0x10000000, 0x0, 8},
|
||||
{0xac, 0x0, 0x20000000, 0x0, 8},
|
||||
{0xbc, 0x0, 0x20000000, 0x0, 16},
|
||||
{0xcc, 0x0, 0x20000000, 0x0, 16},
|
||||
{0xdc, 0x0, 0x20000000, 0x0, 8},
|
||||
{0xa3, 0x0, 0x40000000, 0x0, 8},
|
||||
{0xb3, 0x0, 0x40000000, 0x0, 16},
|
||||
{0xc3, 0x0, 0x40000000, 0x0, 16},
|
||||
{0xd3, 0x0, 0x40000000, 0x0, 8},
|
||||
{0xa5, 0x0, 0x80000000, 0x0, 8},
|
||||
{0xb5, 0x0, 0x80000000, 0x0, 16},
|
||||
{0xc5, 0x0, 0x80000000, 0x0, 16},
|
||||
{0xd5, 0x0, 0x80000000, 0x0, 8},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NAND_STATUS_FAIL = 0x01,
|
||||
NAND_STATUS_FAIL_N1 = 0x02,
|
||||
NAND_STATUS_TRUE_READY = 0x20,
|
||||
NAND_STATUS_READY = 0x40,
|
||||
NAND_STATUS_WP = 0x80,
|
||||
} NANDStatus;
|
||||
|
||||
typedef enum {
|
||||
/* Standard NAND flash commands */
|
||||
NAND_CMD_READ0 = 0x0,
|
||||
NAND_CMD_READ1 = 0x1,
|
||||
NAND_CMD_RNDOUT = 0x5,
|
||||
NAND_CMD_PAGEPROG = 0x10,
|
||||
NAND_CMD_READOOB = 0x50,
|
||||
NAND_CMD_ERASE1 = 0x60,
|
||||
NAND_CMD_STATUS = 0x70,
|
||||
NAND_CMD_STATUS_MULTI = 0x71,
|
||||
NAND_CMD_SEQIN = 0x80,
|
||||
NAND_CMD_RNDIN = 0x85,
|
||||
NAND_CMD_READID = 0x90,
|
||||
NAND_CMD_ERASE2 = 0xd0,
|
||||
NAND_CMD_RESET = 0xff,
|
||||
|
||||
/* Extended commands for large page devices */
|
||||
NAND_CMD_READSTART = 0x30,
|
||||
NAND_CMD_RNDOUTSTART = 0xE0,
|
||||
NAND_CMD_CACHEDPROG = 0x15,
|
||||
} NANDCommands;
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem);
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page);
|
||||
|
|
@ -1,170 +1,170 @@
|
|||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,204 +1,204 @@
|
|||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
static uint32_t nand_cur_cmd;
|
||||
static uint32_t nand_addr_count;
|
||||
static uint32_t idcode;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
nand_cur_cmd = cmd;
|
||||
}
|
||||
|
||||
void NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
switch (nand_cur_cmd) {
|
||||
case NAND_CMD_READID:
|
||||
idcode = 0x76ec;
|
||||
break;
|
||||
|
||||
case NAND_CMD_READ0:
|
||||
case NAND_CMD_READ1:
|
||||
case NAND_CMD_READOOB:
|
||||
nand_addr_count++;
|
||||
break;
|
||||
|
||||
case NAND_CMD_RESET:
|
||||
nand_addr_count = 0;
|
||||
idcode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
switch (nand_cur_cmd) {
|
||||
case NAND_CMD_READ0:
|
||||
case NAND_CMD_READ1:
|
||||
return 0x80;
|
||||
|
||||
case NAND_CMD_READOOB:
|
||||
return 0xc0;
|
||||
|
||||
case NAND_CMD_READID:
|
||||
uint8_t tmp = idcode & 0xff;
|
||||
idcode >>= 8;
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
static uint32_t nand_cur_cmd;
|
||||
static uint32_t nand_addr_count;
|
||||
static uint32_t idcode;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
nand_cur_cmd = cmd;
|
||||
}
|
||||
|
||||
void NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
switch (nand_cur_cmd) {
|
||||
case NAND_CMD_READID:
|
||||
idcode = 0x76ec;
|
||||
break;
|
||||
|
||||
case NAND_CMD_READ0:
|
||||
case NAND_CMD_READ1:
|
||||
case NAND_CMD_READOOB:
|
||||
nand_addr_count++;
|
||||
break;
|
||||
|
||||
case NAND_CMD_RESET:
|
||||
nand_addr_count = 0;
|
||||
idcode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
switch (nand_cur_cmd) {
|
||||
case NAND_CMD_READ0:
|
||||
case NAND_CMD_READ1:
|
||||
return 0x80;
|
||||
|
||||
case NAND_CMD_READOOB:
|
||||
return 0xc0;
|
||||
|
||||
case NAND_CMD_READID:
|
||||
uint8_t tmp = idcode & 0xff;
|
||||
idcode >>= 8;
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,153 +1,153 @@
|
|||
// Intel XScale PXA312 NAND Controller
|
||||
// Found in Samsung SGH-i740 and i780
|
||||
// SGH-i900 uses PXA3xx series, but uses standard OneNAND flash registers at 0x10000000 (K5W2G1HACA)
|
||||
#include "../controller.h"
|
||||
#include "pxa312.h"
|
||||
|
||||
#define PXA3_CMD(cmd, cmd_type, addr_c) (cmd | (cmd_type << PXA3_NDCB_CMD_TYPE.bit_pos) | (addr_c << PXA3_NDCB_ADDR_CYC.bit_pos))
|
||||
#define PXA3_CMD_DBC(cmd1, cmd2, cmd_type, addr_c) (cmd1 | (cmd2 << 8) | (cmd_type << PXA3_NDCB_CMD_TYPE.bit_pos) | (addr_c << PXA3_NDCB_ADDR_CYC.bit_pos) | (1 << PXA3_NDCB_DBC.bit_pos))
|
||||
|
||||
|
||||
void inline PXA3_Start() {
|
||||
WRITE_U32(PXA3_REG_NDSR, 0xfff);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 1);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_WRCMDREQ)));
|
||||
}
|
||||
|
||||
void inline PXA3_Stop() {
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 0);
|
||||
}
|
||||
|
||||
void inline PXA3_NAND_Reset() {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_RESET, PXA3_NDCB_TYPE_RESET, 0));
|
||||
WRITE_U32(PXA3_REG_NDCB1, 0);
|
||||
WRITE_U32(PXA3_REG_NDCB2, 0);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_CS0_CMDD)));
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDY)));
|
||||
}
|
||||
|
||||
uint32_t inline PXA3_NAND_ReadId() {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_READID, PXA3_NDCB_TYPE_READID, 0));
|
||||
WRITE_U32(PXA3_REG_NDCB1, 0);
|
||||
WRITE_U32(PXA3_REG_NDCB2, 0);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDDREQ)));
|
||||
|
||||
return READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
uint32_t inline PXA3_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DMA_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ECC_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_ARB_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_SPARE_EN, 1);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RD_ID_CNT, 4);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RA_START, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PG_PER_BLK, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PAGE_SZ, 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_C, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_M, 0);
|
||||
|
||||
PXA3_Start();
|
||||
|
||||
PXA3_NAND_Reset();
|
||||
uint32_t nand_idcode = PXA3_NAND_ReadId();
|
||||
|
||||
uint8_t mfr_id = (uint8_t)nand_idcode;
|
||||
uint8_t dev_id = (uint8_t)(nand_idcode >> 8);
|
||||
uint8_t ext_id = (uint8_t)(nand_idcode >> 24);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
PXA3_Stop();
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RA_START, mem->page_size > 512 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PG_PER_BLK, mem->page_size > 512 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PAGE_SZ, mem->page_size > 512 ? 1 : 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_C, mem->bit_width == 16 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_M, mem->bit_width == 16 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ECC_EN, 1);
|
||||
|
||||
PXA3_Start();
|
||||
PXA3_NAND_Reset();
|
||||
PXA3_Stop();
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
PXA3_Start();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_READ0, PXA3_NDCB_TYPE_READ, 4));
|
||||
WRITE_U32(PXA3_REG_NDCB1, page << 8);
|
||||
WRITE_U32(PXA3_REG_NDCB2, page >> 24);
|
||||
} else {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD_DBC(NAND_CMD_READ0, NAND_CMD_READSTART, PXA3_NDCB_TYPE_READ, 5));
|
||||
WRITE_U32(PXA3_REG_NDCB1, page << 16);
|
||||
WRITE_U32(PXA3_REG_NDCB2, page >> 16);
|
||||
}
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDDREQ)));
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 2); i++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(page_buf))[i] = READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> 2); i++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(spare_buf))[i] = READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
PXA3_Stop();
|
||||
return DCC_OK;
|
||||
// Intel XScale PXA312 NAND Controller
|
||||
// Found in Samsung SGH-i740 and i780
|
||||
// SGH-i900 uses PXA3xx series, but uses standard OneNAND flash registers at 0x10000000 (K5W2G1HACA)
|
||||
#include "../controller.h"
|
||||
#include "pxa312.h"
|
||||
|
||||
#define PXA3_CMD(cmd, cmd_type, addr_c) (cmd | (cmd_type << PXA3_NDCB_CMD_TYPE.bit_pos) | (addr_c << PXA3_NDCB_ADDR_CYC.bit_pos))
|
||||
#define PXA3_CMD_DBC(cmd1, cmd2, cmd_type, addr_c) (cmd1 | (cmd2 << 8) | (cmd_type << PXA3_NDCB_CMD_TYPE.bit_pos) | (addr_c << PXA3_NDCB_ADDR_CYC.bit_pos) | (1 << PXA3_NDCB_DBC.bit_pos))
|
||||
|
||||
|
||||
void inline PXA3_Start() {
|
||||
WRITE_U32(PXA3_REG_NDSR, 0xfff);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 1);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_WRCMDREQ)));
|
||||
}
|
||||
|
||||
void inline PXA3_Stop() {
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 0);
|
||||
}
|
||||
|
||||
void inline PXA3_NAND_Reset() {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_RESET, PXA3_NDCB_TYPE_RESET, 0));
|
||||
WRITE_U32(PXA3_REG_NDCB1, 0);
|
||||
WRITE_U32(PXA3_REG_NDCB2, 0);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_CS0_CMDD)));
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDY)));
|
||||
}
|
||||
|
||||
uint32_t inline PXA3_NAND_ReadId() {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_READID, PXA3_NDCB_TYPE_READID, 0));
|
||||
WRITE_U32(PXA3_REG_NDCB1, 0);
|
||||
WRITE_U32(PXA3_REG_NDCB2, 0);
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDDREQ)));
|
||||
|
||||
return READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
uint32_t inline PXA3_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DMA_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ECC_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_RUN, 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ND_ARB_EN, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_SPARE_EN, 1);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RD_ID_CNT, 4);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RA_START, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PG_PER_BLK, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PAGE_SZ, 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_C, 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_M, 0);
|
||||
|
||||
PXA3_Start();
|
||||
|
||||
PXA3_NAND_Reset();
|
||||
uint32_t nand_idcode = PXA3_NAND_ReadId();
|
||||
|
||||
uint8_t mfr_id = (uint8_t)nand_idcode;
|
||||
uint8_t dev_id = (uint8_t)(nand_idcode >> 8);
|
||||
uint8_t ext_id = (uint8_t)(nand_idcode >> 24);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
PXA3_Stop();
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_RA_START, mem->page_size > 512 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PG_PER_BLK, mem->page_size > 512 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_PAGE_SZ, mem->page_size > 512 ? 1 : 0);
|
||||
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_C, mem->bit_width == 16 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_DWIDTH_M, mem->bit_width == 16 ? 1 : 0);
|
||||
SET_BIT32(PXA3_REG_NDCR, PXA3_NDCR_ECC_EN, 1);
|
||||
|
||||
PXA3_Start();
|
||||
PXA3_NAND_Reset();
|
||||
PXA3_Stop();
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
PXA3_Start();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD(NAND_CMD_READ0, PXA3_NDCB_TYPE_READ, 4));
|
||||
WRITE_U32(PXA3_REG_NDCB1, page << 8);
|
||||
WRITE_U32(PXA3_REG_NDCB2, page >> 24);
|
||||
} else {
|
||||
WRITE_U32(PXA3_REG_NDCB0, PXA3_CMD_DBC(NAND_CMD_READ0, NAND_CMD_READSTART, PXA3_NDCB_TYPE_READ, 5));
|
||||
WRITE_U32(PXA3_REG_NDCB1, page << 16);
|
||||
WRITE_U32(PXA3_REG_NDCB2, page >> 16);
|
||||
}
|
||||
|
||||
do { wdog_reset(); } while (!(GET_BIT32(PXA3_REG_NDSR, PXA3_NDSR_RDDREQ)));
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 2); i++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(page_buf))[i] = READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> 2); i++) {
|
||||
wdog_reset();
|
||||
((uint32_t *)(spare_buf))[i] = READ_U32(PXA3_REG_NDDB);
|
||||
}
|
||||
|
||||
PXA3_Stop();
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,69 +1,69 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define PXA3_NAND_BASE_REG 0x43100000
|
||||
|
||||
#define PXA3_REG_NDCR PXA3_NAND_BASE_REG + 0x00
|
||||
#define PXA3_REG_NDTR0CS0 PXA3_NAND_BASE_REG + 0x04
|
||||
#define PXA3_REG_NDTR1CS0 PXA3_NAND_BASE_REG + 0x0C
|
||||
#define PXA3_REG_NDSR PXA3_NAND_BASE_REG + 0x14
|
||||
#define PXA3_REG_NDPCR PXA3_NAND_BASE_REG + 0x18
|
||||
#define PXA3_REG_NDBDR0 PXA3_NAND_BASE_REG + 0x1C
|
||||
#define PXA3_REG_NDBDR1 PXA3_NAND_BASE_REG + 0x20
|
||||
#define PXA3_REG_NDECCCTRL PXA3_NAND_BASE_REG + 0x28
|
||||
#define PXA3_REG_NDDB PXA3_NAND_BASE_REG + 0x40
|
||||
#define PXA3_REG_NDCB0 PXA3_NAND_BASE_REG + 0x48
|
||||
#define PXA3_REG_NDCB1 PXA3_NAND_BASE_REG + 0x4C
|
||||
#define PXA3_REG_NDCB2 PXA3_NAND_BASE_REG + 0x50
|
||||
|
||||
bitmask PXA3_NDCR_SPARE_EN = {31, 0x1};
|
||||
bitmask PXA3_NDCR_ECC_EN = {30, 0x1};
|
||||
bitmask PXA3_NDCR_DMA_EN = {29, 0x1};
|
||||
bitmask PXA3_NDCR_ND_RUN = {28, 0x1};
|
||||
bitmask PXA3_NDCR_DWIDTH_C = {27, 0x1};
|
||||
bitmask PXA3_NDCR_DWIDTH_M = {26, 0x1};
|
||||
bitmask PXA3_NDCR_PAGE_SZ = {24, 0x1};
|
||||
bitmask PXA3_NDCR_NCSX = {23, 0x1};
|
||||
bitmask PXA3_NDCR_CLR_PG_CNT = {20, 0x1};
|
||||
bitmask PXA3_NDCR_STOP_ON_UNCOR = {19, 0x1};
|
||||
bitmask PXA3_NDCR_RD_ID_CNT = {16, 0x7};
|
||||
bitmask PXA3_NDCR_RA_START = {15, 0x1};
|
||||
bitmask PXA3_NDCR_PG_PER_BLK = {14, 0x1};
|
||||
bitmask PXA3_NDCR_ND_ARB_EN = {12, 0x1};
|
||||
bitmask PXA3_NDCR_INTERRUPT = {0, 0xfff};
|
||||
|
||||
bitmask PXA3_NDSR_MASK = {0, 0xfff};
|
||||
bitmask PXA3_NDSR_RDY = {12, 0x1};
|
||||
bitmask PXA3_NDSR_FLASH_RDY = {11, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_PAGED = {10, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_PAGED = {9, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_CMDD = {8, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_CMDD = {7, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_BBD = {6, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_BBD = {5, 0x1};
|
||||
bitmask PXA3_NDSR_UNCORERR = {4, 0x1};
|
||||
bitmask PXA3_NDSR_CORERR = {3, 0x1};
|
||||
bitmask PXA3_NDSR_WRDREQ = {2, 0x1};
|
||||
bitmask PXA3_NDSR_RDDREQ = {1, 0x1};
|
||||
bitmask PXA3_NDSR_WRCMDREQ = {0, 0x1};
|
||||
|
||||
bitmask PXA3_NDCB_LEN_OVRD = {28, 0x1};
|
||||
bitmask PXA3_NDCB_ST_ROW_EN = {26, 0x1};
|
||||
bitmask PXA3_NDCB_AUTO_RS = {25, 0x1};
|
||||
bitmask PXA3_NDCB_CSEL = {24, 0x1};
|
||||
bitmask PXA3_NDCB_EXT_CMD_TYPE = {29, 0x7};
|
||||
bitmask PXA3_NDCB_CMD_TYPE = {21, 0x7};
|
||||
bitmask PXA3_NDCB_NC = {20, 0x1};
|
||||
bitmask PXA3_NDCB_DBC = {19, 0x1};
|
||||
bitmask PXA3_NDCB_ADDR_CYC = {16, 0x7};
|
||||
bitmask PXA3_NDCB_CMD2 = {8, 0xff};
|
||||
bitmask PXA3_NDCB_CMD1 = {0, 0xff};
|
||||
|
||||
typedef enum {
|
||||
PXA3_NDCB_TYPE_READ,
|
||||
PXA3_NDCB_TYPE_WRITE,
|
||||
PXA3_NDCB_TYPE_ERASE,
|
||||
PXA3_NDCB_TYPE_READID,
|
||||
PXA3_NDCB_TYPE_STATUS_READ,
|
||||
PXA3_NDCB_TYPE_RESET
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define PXA3_NAND_BASE_REG 0x43100000
|
||||
|
||||
#define PXA3_REG_NDCR PXA3_NAND_BASE_REG + 0x00
|
||||
#define PXA3_REG_NDTR0CS0 PXA3_NAND_BASE_REG + 0x04
|
||||
#define PXA3_REG_NDTR1CS0 PXA3_NAND_BASE_REG + 0x0C
|
||||
#define PXA3_REG_NDSR PXA3_NAND_BASE_REG + 0x14
|
||||
#define PXA3_REG_NDPCR PXA3_NAND_BASE_REG + 0x18
|
||||
#define PXA3_REG_NDBDR0 PXA3_NAND_BASE_REG + 0x1C
|
||||
#define PXA3_REG_NDBDR1 PXA3_NAND_BASE_REG + 0x20
|
||||
#define PXA3_REG_NDECCCTRL PXA3_NAND_BASE_REG + 0x28
|
||||
#define PXA3_REG_NDDB PXA3_NAND_BASE_REG + 0x40
|
||||
#define PXA3_REG_NDCB0 PXA3_NAND_BASE_REG + 0x48
|
||||
#define PXA3_REG_NDCB1 PXA3_NAND_BASE_REG + 0x4C
|
||||
#define PXA3_REG_NDCB2 PXA3_NAND_BASE_REG + 0x50
|
||||
|
||||
bitmask PXA3_NDCR_SPARE_EN = {31, 0x1};
|
||||
bitmask PXA3_NDCR_ECC_EN = {30, 0x1};
|
||||
bitmask PXA3_NDCR_DMA_EN = {29, 0x1};
|
||||
bitmask PXA3_NDCR_ND_RUN = {28, 0x1};
|
||||
bitmask PXA3_NDCR_DWIDTH_C = {27, 0x1};
|
||||
bitmask PXA3_NDCR_DWIDTH_M = {26, 0x1};
|
||||
bitmask PXA3_NDCR_PAGE_SZ = {24, 0x1};
|
||||
bitmask PXA3_NDCR_NCSX = {23, 0x1};
|
||||
bitmask PXA3_NDCR_CLR_PG_CNT = {20, 0x1};
|
||||
bitmask PXA3_NDCR_STOP_ON_UNCOR = {19, 0x1};
|
||||
bitmask PXA3_NDCR_RD_ID_CNT = {16, 0x7};
|
||||
bitmask PXA3_NDCR_RA_START = {15, 0x1};
|
||||
bitmask PXA3_NDCR_PG_PER_BLK = {14, 0x1};
|
||||
bitmask PXA3_NDCR_ND_ARB_EN = {12, 0x1};
|
||||
bitmask PXA3_NDCR_INTERRUPT = {0, 0xfff};
|
||||
|
||||
bitmask PXA3_NDSR_MASK = {0, 0xfff};
|
||||
bitmask PXA3_NDSR_RDY = {12, 0x1};
|
||||
bitmask PXA3_NDSR_FLASH_RDY = {11, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_PAGED = {10, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_PAGED = {9, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_CMDD = {8, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_CMDD = {7, 0x1};
|
||||
bitmask PXA3_NDSR_CS0_BBD = {6, 0x1};
|
||||
bitmask PXA3_NDSR_CS1_BBD = {5, 0x1};
|
||||
bitmask PXA3_NDSR_UNCORERR = {4, 0x1};
|
||||
bitmask PXA3_NDSR_CORERR = {3, 0x1};
|
||||
bitmask PXA3_NDSR_WRDREQ = {2, 0x1};
|
||||
bitmask PXA3_NDSR_RDDREQ = {1, 0x1};
|
||||
bitmask PXA3_NDSR_WRCMDREQ = {0, 0x1};
|
||||
|
||||
bitmask PXA3_NDCB_LEN_OVRD = {28, 0x1};
|
||||
bitmask PXA3_NDCB_ST_ROW_EN = {26, 0x1};
|
||||
bitmask PXA3_NDCB_AUTO_RS = {25, 0x1};
|
||||
bitmask PXA3_NDCB_CSEL = {24, 0x1};
|
||||
bitmask PXA3_NDCB_EXT_CMD_TYPE = {29, 0x7};
|
||||
bitmask PXA3_NDCB_CMD_TYPE = {21, 0x7};
|
||||
bitmask PXA3_NDCB_NC = {20, 0x1};
|
||||
bitmask PXA3_NDCB_DBC = {19, 0x1};
|
||||
bitmask PXA3_NDCB_ADDR_CYC = {16, 0x7};
|
||||
bitmask PXA3_NDCB_CMD2 = {8, 0xff};
|
||||
bitmask PXA3_NDCB_CMD1 = {0, 0xff};
|
||||
|
||||
typedef enum {
|
||||
PXA3_NDCB_TYPE_READ,
|
||||
PXA3_NDCB_TYPE_WRITE,
|
||||
PXA3_NDCB_TYPE_ERASE,
|
||||
PXA3_NDCB_TYPE_READID,
|
||||
PXA3_NDCB_TYPE_STATUS_READ,
|
||||
PXA3_NDCB_TYPE_RESET
|
||||
} PXA3_NDCB_TYPE;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#define REGS_START 0x0c000000
|
||||
#define INTERRUPT_WRITE 0x03000a84
|
||||
#define INTERRUPT_READ 0x03000a84
|
||||
#define INTERRUPT_CLEAR_VALUE 0xc
|
||||
#define INTERRUPT_ASSERT_VALUE 0x4
|
||||
|
||||
#define REGS_START 0x0c000000
|
||||
#define INTERRUPT_WRITE 0x03000a84
|
||||
#define INTERRUPT_READ 0x03000a84
|
||||
#define INTERRUPT_CLEAR_VALUE 0xc
|
||||
#define INTERRUPT_ASSERT_VALUE 0x4
|
||||
|
||||
#include "msm6250.c"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#define INTERRUPT_WRITE 0x80000c84
|
||||
#define INTERRUPT_READ 0x80000c84
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#define INTERRUPT_WRITE 0x80000c84
|
||||
#define INTERRUPT_READ 0x80000c84
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#include "msm6250.c"
|
||||
|
|
@ -1,106 +1,106 @@
|
|||
// Qualcomm MSM625x NAND Controller
|
||||
#include "../controller.h"
|
||||
#include "msm6250.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0x64000000
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_WRITE
|
||||
#define INTERRUPT_WRITE 0x8400024c
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_READ
|
||||
#define INTERRUPT_READ 0x84000244
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_CLEAR_VALUE
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_ASSERT_VALUE
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2
|
||||
#endif
|
||||
|
||||
#ifndef IS_MSM6550
|
||||
#define IS_MSM6550 0
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config;
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(INTERRUPT_WRITE, INTERRUPT_CLEAR_VALUE);
|
||||
do { wdog_reset(); } while (READ_U32(INTERRUPT_READ) & INTERRUPT_CLEAR_VALUE);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CMD, cmd);
|
||||
do { wdog_reset(); } while ((READ_U32(INTERRUPT_READ) & INTERRUPT_ASSERT_VALUE) == 0);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
#if IS_MSM6550
|
||||
nand_config = 0x2;
|
||||
#else
|
||||
nand_config = 0x253;
|
||||
#endif
|
||||
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CFG1, nand_config);
|
||||
#if IS_MSM6550
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_SPARE_DATA, 0x06541463);
|
||||
#endif
|
||||
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET_NAND);
|
||||
RunCommand(MSM6250_CMD_FLASH_ID_FETCH);
|
||||
RunCommand(MSM6250_CMD_FLASH_STATUS_CHECK);
|
||||
|
||||
uint8_t mfr_id = (uint8_t)GET_BIT32(REGS_START + MSM6250_REG_FLASH_STATUS, MSM6250_STATUS_NAND_MFRID);
|
||||
uint8_t dev_id = (uint8_t)GET_BIT32(REGS_START + MSM6250_REG_FLASH_STATUS, MSM6250_STATUS_NAND_DEVID);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id && flash_ids[i].page_size) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
#if IS_MSM6550
|
||||
BIT_SET_VAR(nand_config, MSM6250_CONFIG_WIDE_NAND, mem->bit_width == 16 ? 1 : 0);
|
||||
#else
|
||||
nand_config = 0x25a;
|
||||
#endif
|
||||
|
||||
BIT_SET_VAR(nand_config, MSM6250_CONFIG_ECC_DISABLED, 0);
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CFG1, nand_config);
|
||||
#if IS_MSM6550
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_SPARE_DATA, mem->bit_width == 16 ? 0x06719C63 : 0x06541463);
|
||||
#endif
|
||||
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET);
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SET_BIT32(REGS_START + MSM6250_REG_FLASH_ADDR, MSM6250_ADDR_FLASH_PAGE_ADDRESS, page);
|
||||
RunCommand(MSM6250_CMD_FLASH_PAGE_READ);
|
||||
|
||||
PLAT_MEMCPY(page_buf, (uint8_t *)(REGS_START + MSM6250_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf, (uint8_t *)(REGS_START + MSM6250_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
|
||||
return DCC_OK;
|
||||
// Qualcomm MSM625x NAND Controller
|
||||
#include "../controller.h"
|
||||
#include "msm6250.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0x64000000
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_WRITE
|
||||
#define INTERRUPT_WRITE 0x8400024c
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_READ
|
||||
#define INTERRUPT_READ 0x84000244
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_CLEAR_VALUE
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_ASSERT_VALUE
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2
|
||||
#endif
|
||||
|
||||
#ifndef IS_MSM6550
|
||||
#define IS_MSM6550 0
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config;
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(INTERRUPT_WRITE, INTERRUPT_CLEAR_VALUE);
|
||||
do { wdog_reset(); } while (READ_U32(INTERRUPT_READ) & INTERRUPT_CLEAR_VALUE);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CMD, cmd);
|
||||
do { wdog_reset(); } while ((READ_U32(INTERRUPT_READ) & INTERRUPT_ASSERT_VALUE) == 0);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
#if IS_MSM6550
|
||||
nand_config = 0x2;
|
||||
#else
|
||||
nand_config = 0x253;
|
||||
#endif
|
||||
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CFG1, nand_config);
|
||||
#if IS_MSM6550
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_SPARE_DATA, 0x06541463);
|
||||
#endif
|
||||
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET_NAND);
|
||||
RunCommand(MSM6250_CMD_FLASH_ID_FETCH);
|
||||
RunCommand(MSM6250_CMD_FLASH_STATUS_CHECK);
|
||||
|
||||
uint8_t mfr_id = (uint8_t)GET_BIT32(REGS_START + MSM6250_REG_FLASH_STATUS, MSM6250_STATUS_NAND_MFRID);
|
||||
uint8_t dev_id = (uint8_t)GET_BIT32(REGS_START + MSM6250_REG_FLASH_STATUS, MSM6250_STATUS_NAND_DEVID);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id && flash_ids[i].page_size) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
#if IS_MSM6550
|
||||
BIT_SET_VAR(nand_config, MSM6250_CONFIG_WIDE_NAND, mem->bit_width == 16 ? 1 : 0);
|
||||
#else
|
||||
nand_config = 0x25a;
|
||||
#endif
|
||||
|
||||
BIT_SET_VAR(nand_config, MSM6250_CONFIG_ECC_DISABLED, 0);
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_CFG1, nand_config);
|
||||
#if IS_MSM6550
|
||||
WRITE_U32(REGS_START + MSM6250_REG_FLASH_SPARE_DATA, mem->bit_width == 16 ? 0x06719C63 : 0x06541463);
|
||||
#endif
|
||||
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET);
|
||||
RunCommand(MSM6250_CMD_FLASH_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SET_BIT32(REGS_START + MSM6250_REG_FLASH_ADDR, MSM6250_ADDR_FLASH_PAGE_ADDRESS, page);
|
||||
RunCommand(MSM6250_CMD_FLASH_PAGE_READ);
|
||||
|
||||
PLAT_MEMCPY(page_buf, (uint8_t *)(REGS_START + MSM6250_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf, (uint8_t *)(REGS_START + MSM6250_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,57 +1,57 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM6250_REG_FLASH_BUFFER 0x0
|
||||
#define MSM6250_REG_FLASH_CMD 0x300
|
||||
#define MSM6250_REG_FLASH_ADDR 0x304
|
||||
#define MSM6250_REG_FLASH_STATUS 0x308
|
||||
#define MSM6250_REG_FLASH_CFG1 0x31C
|
||||
#define MSM6250_REG_FLASH_SPARE_DATA 0x320
|
||||
|
||||
#define MSM6250_CMD_FLASH_RESET 0
|
||||
#define MSM6250_CMD_FLASH_PAGE_READ 1
|
||||
#define MSM6250_CMD_FLASH_FLAG_READ 2
|
||||
#define MSM6250_CMD_FLASH_PAGE_WRITE 3
|
||||
#define MSM6250_CMD_FLASH_BLOCK_ERASE 4
|
||||
#define MSM6250_CMD_FLASH_ID_FETCH 5
|
||||
#define MSM6250_CMD_FLASH_STATUS_CHECK 6
|
||||
#define MSM6250_CMD_FLASH_RESET_NAND 7
|
||||
|
||||
bitmask MSM6250_ADDR_SPARE_AREA_BYTE_ADDRESS = {0, 0x3f};
|
||||
bitmask MSM6250_ADDR_FLASH_PAGE_ADDRESS = {9, 0x7fffff};
|
||||
|
||||
bitmask MSM6250_CMD_OP_CMD = {0, 0x7};
|
||||
bitmask MSM6250_CMD_SW_CMD_EN = {3, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD_VAL = {4, 0xff};
|
||||
bitmask MSM6250_CMD_SW_CMD_ADDR_SEL = {12, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD1_REPLACE = {13, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD2_REPLACE = {14, 0x1};
|
||||
|
||||
bitmask MSM6250_STATUS_OP_STATUS = {0, 0x7};
|
||||
bitmask MSM6250_STATUS_OP_ERR = {3, 0x1};
|
||||
bitmask MSM6250_STATUS_CORRECTABLE_ERROR = {4, 0x1};
|
||||
bitmask MSM6250_STATUS_READY_BUSY_N = {5, 0x1};
|
||||
bitmask MSM6250_STATUS_ECC_SELF_ERR = {6, 0x1};
|
||||
bitmask MSM6250_STATUS_WRITE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM6250_STATUS_OP_FAILURE = {0, 0x88};
|
||||
bitmask MSM6250_STATUS_READY_BUSY_N_STATUS = {13, 0x1};
|
||||
bitmask MSM6250_STATUS_WRITE_PROTECT = {14, 0x1};
|
||||
bitmask MSM6250_STATUS_NAND_DEVID = {15, 0xff};
|
||||
bitmask MSM6250_STATUS_NAND_MFRID = {23, 0xff};
|
||||
bitmask MSM6250_STATUS_READ_ERROR = {31, 0x1};
|
||||
|
||||
bitmask MSM6250_CONFIG_ECC_DISABLED = {0, 0x1};
|
||||
bitmask MSM6250_CONFIG_BUSFREE_SUPPORT_SELECT = {1, 0x1};
|
||||
bitmask MSM6250_CONFIG_ECC_HALT_DIS = {2, 0x1};
|
||||
bitmask MSM6250_CONFIG_CLK_HALT_DIS = {3, 0x1};
|
||||
bitmask MSM6250_CONFIG_WIDE_NAND = {5, 0x1};
|
||||
bitmask MSM6250_CONFIG_BUFFER_MEM_WRITE_WAIT = {6, 0x1};
|
||||
bitmask MSM6250_CONFIG_ECC_ERR_SELF_DETECT = {7, 0x1};
|
||||
bitmask MSM6250_CONFIG_NAND_RECOVERY_CYCLE = {8, 0x7};
|
||||
|
||||
bitmask MSM6550_CONFIG2_ID_RD_SETUP = {0, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_RD_SETUP = {5, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_RD_ACTIVE = {10, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_WR_HOLD = {15, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_WR_ACTIVE = {20, 0x1f};
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM6250_REG_FLASH_BUFFER 0x0
|
||||
#define MSM6250_REG_FLASH_CMD 0x300
|
||||
#define MSM6250_REG_FLASH_ADDR 0x304
|
||||
#define MSM6250_REG_FLASH_STATUS 0x308
|
||||
#define MSM6250_REG_FLASH_CFG1 0x31C
|
||||
#define MSM6250_REG_FLASH_SPARE_DATA 0x320
|
||||
|
||||
#define MSM6250_CMD_FLASH_RESET 0
|
||||
#define MSM6250_CMD_FLASH_PAGE_READ 1
|
||||
#define MSM6250_CMD_FLASH_FLAG_READ 2
|
||||
#define MSM6250_CMD_FLASH_PAGE_WRITE 3
|
||||
#define MSM6250_CMD_FLASH_BLOCK_ERASE 4
|
||||
#define MSM6250_CMD_FLASH_ID_FETCH 5
|
||||
#define MSM6250_CMD_FLASH_STATUS_CHECK 6
|
||||
#define MSM6250_CMD_FLASH_RESET_NAND 7
|
||||
|
||||
bitmask MSM6250_ADDR_SPARE_AREA_BYTE_ADDRESS = {0, 0x3f};
|
||||
bitmask MSM6250_ADDR_FLASH_PAGE_ADDRESS = {9, 0x7fffff};
|
||||
|
||||
bitmask MSM6250_CMD_OP_CMD = {0, 0x7};
|
||||
bitmask MSM6250_CMD_SW_CMD_EN = {3, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD_VAL = {4, 0xff};
|
||||
bitmask MSM6250_CMD_SW_CMD_ADDR_SEL = {12, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD1_REPLACE = {13, 0x1};
|
||||
bitmask MSM6250_CMD_SW_CMD2_REPLACE = {14, 0x1};
|
||||
|
||||
bitmask MSM6250_STATUS_OP_STATUS = {0, 0x7};
|
||||
bitmask MSM6250_STATUS_OP_ERR = {3, 0x1};
|
||||
bitmask MSM6250_STATUS_CORRECTABLE_ERROR = {4, 0x1};
|
||||
bitmask MSM6250_STATUS_READY_BUSY_N = {5, 0x1};
|
||||
bitmask MSM6250_STATUS_ECC_SELF_ERR = {6, 0x1};
|
||||
bitmask MSM6250_STATUS_WRITE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM6250_STATUS_OP_FAILURE = {0, 0x88};
|
||||
bitmask MSM6250_STATUS_READY_BUSY_N_STATUS = {13, 0x1};
|
||||
bitmask MSM6250_STATUS_WRITE_PROTECT = {14, 0x1};
|
||||
bitmask MSM6250_STATUS_NAND_DEVID = {15, 0xff};
|
||||
bitmask MSM6250_STATUS_NAND_MFRID = {23, 0xff};
|
||||
bitmask MSM6250_STATUS_READ_ERROR = {31, 0x1};
|
||||
|
||||
bitmask MSM6250_CONFIG_ECC_DISABLED = {0, 0x1};
|
||||
bitmask MSM6250_CONFIG_BUSFREE_SUPPORT_SELECT = {1, 0x1};
|
||||
bitmask MSM6250_CONFIG_ECC_HALT_DIS = {2, 0x1};
|
||||
bitmask MSM6250_CONFIG_CLK_HALT_DIS = {3, 0x1};
|
||||
bitmask MSM6250_CONFIG_WIDE_NAND = {5, 0x1};
|
||||
bitmask MSM6250_CONFIG_BUFFER_MEM_WRITE_WAIT = {6, 0x1};
|
||||
bitmask MSM6250_CONFIG_ECC_ERR_SELF_DETECT = {7, 0x1};
|
||||
bitmask MSM6250_CONFIG_NAND_RECOVERY_CYCLE = {8, 0x7};
|
||||
|
||||
bitmask MSM6550_CONFIG2_ID_RD_SETUP = {0, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_RD_SETUP = {5, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_RD_ACTIVE = {10, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_WR_HOLD = {15, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_WR_ACTIVE = {20, 0x1f};
|
||||
bitmask MSM6550_CONFIG2_WR_SETUP = {25, 0x1f};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#define INTERRUPT_WRITE 0x80000904
|
||||
#define INTERRUPT_READ 0x80000950
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#define INTERRUPT_WRITE 0x80000904
|
||||
#define INTERRUPT_READ 0x80000950
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#include "msm6250.c"
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#define REGS_START 0x60000000
|
||||
#define INTERRUPT_WRITE 0x80000904
|
||||
#define INTERRUPT_READ 0x80000958
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
#define IS_MSM6550 1
|
||||
|
||||
#define REGS_START 0x60000000
|
||||
#define INTERRUPT_WRITE 0x80000904
|
||||
#define INTERRUPT_READ 0x80000958
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
#define IS_MSM6550 1
|
||||
|
||||
#include "msm6250.c"
|
||||
|
|
@ -1,135 +1,135 @@
|
|||
// Qualcomm MSM62xx (except MSM625x group) NAND Controller
|
||||
// OneNAND is handled by default onenand controller at 0x40000000 (Boot from OneNAND is supported on XMEM2_CS_N[3])
|
||||
#include "../controller.h"
|
||||
#include "msm6800.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0x60000000
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_WRITE
|
||||
#define INTERRUPT_WRITE 0x80000414
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_READ
|
||||
#define INTERRUPT_READ 0x80000488
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_CLEAR_VALUE
|
||||
#define INTERRUPT_CLEAR_VALUE 0x2
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_ASSERT_VALUE
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config_1;
|
||||
static uint32_t nand_config_2;
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(INTERRUPT_WRITE, INTERRUPT_CLEAR_VALUE);
|
||||
do { wdog_reset(); } while (READ_U32(INTERRUPT_READ) & INTERRUPT_CLEAR_VALUE);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CMD, cmd);
|
||||
do { wdog_reset(); } while ((READ_U32(INTERRUPT_READ) & INTERRUPT_ASSERT_VALUE) == 0);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
nand_config_1 = 0xa2;
|
||||
nand_config_2 = 0x22;
|
||||
// nand_config_1 = READ_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1);
|
||||
// nand_config_2 = READ_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1, nand_config_2);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET_NAND);
|
||||
if (!GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_DONE)) {
|
||||
uint32_t prev_common = READ_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, BIT_SET(0, MSM6800_COMMONCFG_NAND_AUTOPROBE, 1));
|
||||
RunCommand(MSM6800_CMD_FLASH_PAGE_READ);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, prev_common);
|
||||
}
|
||||
|
||||
uint32_t page_size_type = GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_ISLARGE);
|
||||
uint32_t page_width_type = GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_IS16BIT);
|
||||
|
||||
nand_config_1 = 0xa;
|
||||
nand_config_2 = 0x4219442;
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_PAGE_IS_2KB, page_size_type);
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_WIDE_NAND, page_width_type);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1, nand_config_2);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, 0x3);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_ID_FETCH);
|
||||
RunCommand(MSM6800_CMD_FLASH_STATUS_CHECK);
|
||||
|
||||
uint8_t mfr_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_MFRID);
|
||||
uint8_t dev_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_DEVID);
|
||||
uint8_t ext_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_EXTID);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_ECC_DISABLED, 0);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET);
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SET_BIT32(REGS_START + MSM6800_REG_FLASH_ADDR, MSM6800_ADDR_FLASH_PAGE_ADDRESS, page);
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 9); i++) {
|
||||
RunCommand(MSM6800_CMD_FLASH_PAGE_READ);
|
||||
PLAT_MEMCPY(page_buf + (i << 9), (uint8_t *)(REGS_START + MSM6800_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf + (i << 4), (uint8_t *)(REGS_START + MSM6800_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
// Qualcomm MSM62xx (except MSM625x group) NAND Controller
|
||||
// OneNAND is handled by default onenand controller at 0x40000000 (Boot from OneNAND is supported on XMEM2_CS_N[3])
|
||||
#include "../controller.h"
|
||||
#include "msm6800.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0x60000000
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_WRITE
|
||||
#define INTERRUPT_WRITE 0x80000414
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_READ
|
||||
#define INTERRUPT_READ 0x80000488
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_CLEAR_VALUE
|
||||
#define INTERRUPT_CLEAR_VALUE 0x2
|
||||
#endif
|
||||
|
||||
#ifndef INTERRUPT_ASSERT_VALUE
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config_1;
|
||||
static uint32_t nand_config_2;
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(INTERRUPT_WRITE, INTERRUPT_CLEAR_VALUE);
|
||||
do { wdog_reset(); } while (READ_U32(INTERRUPT_READ) & INTERRUPT_CLEAR_VALUE);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CMD, cmd);
|
||||
do { wdog_reset(); } while ((READ_U32(INTERRUPT_READ) & INTERRUPT_ASSERT_VALUE) == 0);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
nand_config_1 = 0xa2;
|
||||
nand_config_2 = 0x22;
|
||||
// nand_config_1 = READ_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1);
|
||||
// nand_config_2 = READ_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1, nand_config_2);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET_NAND);
|
||||
if (!GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_DONE)) {
|
||||
uint32_t prev_common = READ_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, BIT_SET(0, MSM6800_COMMONCFG_NAND_AUTOPROBE, 1));
|
||||
RunCommand(MSM6800_CMD_FLASH_PAGE_READ);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, prev_common);
|
||||
}
|
||||
|
||||
uint32_t page_size_type = GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_ISLARGE);
|
||||
uint32_t page_width_type = GET_BIT32(REGS_START + MSM6800_REG_FLASH_STATUS, MSM6800_STATUS_NAND_AUTOPROBE_IS16BIT);
|
||||
|
||||
nand_config_1 = 0xa;
|
||||
nand_config_2 = 0x4219442;
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_PAGE_IS_2KB, page_size_type);
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_WIDE_NAND, page_width_type);
|
||||
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG2_FLASH1, nand_config_2);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_COMMON_CFG, 0x3);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_ID_FETCH);
|
||||
RunCommand(MSM6800_CMD_FLASH_STATUS_CHECK);
|
||||
|
||||
uint8_t mfr_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_MFRID);
|
||||
uint8_t dev_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_DEVID);
|
||||
uint8_t ext_id = (uint8_t)GET_BIT32(REGS_START + MSM6800_REG_FLASH_ID_DATA, MSM6800_FLASH_NAND_EXTID);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM6800_CONFIG1_ECC_DISABLED, 0);
|
||||
WRITE_U32(REGS_START + MSM6800_REG_FLASH_CFG1_FLASH1, nand_config_1);
|
||||
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET);
|
||||
RunCommand(MSM6800_CMD_FLASH_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SET_BIT32(REGS_START + MSM6800_REG_FLASH_ADDR, MSM6800_ADDR_FLASH_PAGE_ADDRESS, page);
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 9); i++) {
|
||||
RunCommand(MSM6800_CMD_FLASH_PAGE_READ);
|
||||
PLAT_MEMCPY(page_buf + (i << 9), (uint8_t *)(REGS_START + MSM6800_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf + (i << 4), (uint8_t *)(REGS_START + MSM6800_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,73 +1,73 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM6800_REG_FLASH_BUFFER 0x0
|
||||
#define MSM6800_REG_FLASH_ADDR 0x300
|
||||
#define MSM6800_REG_FLASH_CMD 0x304
|
||||
#define MSM6800_REG_FLASH_STATUS 0x308
|
||||
#define MSM6800_REG_FLASH_COMMON_CFG 0x31C
|
||||
#define MSM6800_REG_FLASH_ID_DATA 0x320
|
||||
#define MSM6800_REG_FLASH_SPARE_DATA 0x324
|
||||
#define MSM6800_REG_FLASH_CFG1_FLASH1 0x328
|
||||
#define MSM6800_REG_FLASH_CFG1_FLASH2 0x32c
|
||||
#define MSM6800_REG_FLASH_CFG2_FLASH1 0x330
|
||||
#define MSM6800_REG_FLASH_CFG2_FLASH2 0x334
|
||||
|
||||
#define MSM6800_CMD_FLASH_RESET 0
|
||||
#define MSM6800_CMD_FLASH_PAGE_READ 1
|
||||
#define MSM6800_CMD_FLASH_FLAG_READ 2
|
||||
#define MSM6800_CMD_FLASH_PAGE_WRITE 3
|
||||
#define MSM6800_CMD_FLASH_BLOCK_ERASE 4
|
||||
#define MSM6800_CMD_FLASH_ID_FETCH 5
|
||||
#define MSM6800_CMD_FLASH_STATUS_CHECK 6
|
||||
#define MSM6800_CMD_FLASH_RESET_NAND 7
|
||||
|
||||
bitmask MSM6800_ADDR_SPARE_AREA_BYTE_ADDRESS = {0, 0x3f};
|
||||
bitmask MSM6800_ADDR_FLASH_PAGE_ADDRESS = {9, 0x7fffff};
|
||||
|
||||
bitmask MSM6800_CMD_OP_CMD = {0, 0x7};
|
||||
bitmask MSM6800_CMD_SW_CMD_EN = {3, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD_VAL = {4, 0xff};
|
||||
bitmask MSM6800_CMD_SW_CMD_ADDR_SEL = {12, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD1_REPLACE = {13, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD2_REPLACE = {14, 0x1};
|
||||
|
||||
bitmask MSM6800_STATUS_OP_STATUS = {0, 0x7};
|
||||
bitmask MSM6800_STATUS_OP_ERR = {3, 0x1};
|
||||
bitmask MSM6800_STATUS_CORRECTABLE_ERROR = {4, 0x1};
|
||||
bitmask MSM6800_STATUS_READY_BUSY_N = {5, 0x1};
|
||||
bitmask MSM6800_STATUS_ECC_SELF_ERR = {6, 0x1};
|
||||
bitmask MSM6800_STATUS_WRITE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM6800_STATUS_OP_FAILURE = {0, 0x88};
|
||||
bitmask MSM6800_STATUS_READY_BUSY_N_STATUS = {13, 0x1};
|
||||
bitmask MSM6800_STATUS_WRITE_PROTECT = {14, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_DONE = {15, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_ISLARGE = {16, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_IS16BIT = {17, 0x1};
|
||||
bitmask MSM6800_STATUS_READ_ERROR = {31, 0x1};
|
||||
|
||||
bitmask MSM6800_COMMONCFG_BUFFER_MEM_WRITE_WAIT = {0, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_ECC_ERR_SELF_DETECT = {1, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_ECC_HALT_DIS = {2, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_CLK_HALT_DIS = {3, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_NAND_SEL = {4, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_DM_EN = {5, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_NAND_AUTOPROBE = {6, 0x1};
|
||||
|
||||
bitmask MSM6800_FLASH_NAND_DEVID = {0, 0xff};
|
||||
bitmask MSM6800_FLASH_NAND_MFRID = {8, 0xff};
|
||||
bitmask MSM6800_FLASH_NAND_EXTID = {16, 0xff};
|
||||
|
||||
bitmask MSM6800_CONFIG1_ECC_DISABLED = {0, 0x1};
|
||||
bitmask MSM6800_CONFIG1_BUSFREE_SUPPORT_SELECT = {1, 0x1};
|
||||
bitmask MSM6800_CONFIG1_NAND_SIZE = {2, 0xf};
|
||||
bitmask MSM6800_CONFIG1_PAGE_IS_2KB = {6, 0x1};
|
||||
bitmask MSM6800_CONFIG1_WIDE_NAND = {7, 0x1};
|
||||
bitmask MSM6800_CONFIG1_NAND_RECOVERY_CYCLE = {8, 0x7};
|
||||
|
||||
bitmask MSM6800_CONFIG2_ID_RD_HOLD = {0, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_RD_HOLD = {5, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_RD_SETUP = {10, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_WR_HOLD = {15, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_WR_SETUP = {20, 0x1f};
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM6800_REG_FLASH_BUFFER 0x0
|
||||
#define MSM6800_REG_FLASH_ADDR 0x300
|
||||
#define MSM6800_REG_FLASH_CMD 0x304
|
||||
#define MSM6800_REG_FLASH_STATUS 0x308
|
||||
#define MSM6800_REG_FLASH_COMMON_CFG 0x31C
|
||||
#define MSM6800_REG_FLASH_ID_DATA 0x320
|
||||
#define MSM6800_REG_FLASH_SPARE_DATA 0x324
|
||||
#define MSM6800_REG_FLASH_CFG1_FLASH1 0x328
|
||||
#define MSM6800_REG_FLASH_CFG1_FLASH2 0x32c
|
||||
#define MSM6800_REG_FLASH_CFG2_FLASH1 0x330
|
||||
#define MSM6800_REG_FLASH_CFG2_FLASH2 0x334
|
||||
|
||||
#define MSM6800_CMD_FLASH_RESET 0
|
||||
#define MSM6800_CMD_FLASH_PAGE_READ 1
|
||||
#define MSM6800_CMD_FLASH_FLAG_READ 2
|
||||
#define MSM6800_CMD_FLASH_PAGE_WRITE 3
|
||||
#define MSM6800_CMD_FLASH_BLOCK_ERASE 4
|
||||
#define MSM6800_CMD_FLASH_ID_FETCH 5
|
||||
#define MSM6800_CMD_FLASH_STATUS_CHECK 6
|
||||
#define MSM6800_CMD_FLASH_RESET_NAND 7
|
||||
|
||||
bitmask MSM6800_ADDR_SPARE_AREA_BYTE_ADDRESS = {0, 0x3f};
|
||||
bitmask MSM6800_ADDR_FLASH_PAGE_ADDRESS = {9, 0x7fffff};
|
||||
|
||||
bitmask MSM6800_CMD_OP_CMD = {0, 0x7};
|
||||
bitmask MSM6800_CMD_SW_CMD_EN = {3, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD_VAL = {4, 0xff};
|
||||
bitmask MSM6800_CMD_SW_CMD_ADDR_SEL = {12, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD1_REPLACE = {13, 0x1};
|
||||
bitmask MSM6800_CMD_SW_CMD2_REPLACE = {14, 0x1};
|
||||
|
||||
bitmask MSM6800_STATUS_OP_STATUS = {0, 0x7};
|
||||
bitmask MSM6800_STATUS_OP_ERR = {3, 0x1};
|
||||
bitmask MSM6800_STATUS_CORRECTABLE_ERROR = {4, 0x1};
|
||||
bitmask MSM6800_STATUS_READY_BUSY_N = {5, 0x1};
|
||||
bitmask MSM6800_STATUS_ECC_SELF_ERR = {6, 0x1};
|
||||
bitmask MSM6800_STATUS_WRITE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM6800_STATUS_OP_FAILURE = {0, 0x88};
|
||||
bitmask MSM6800_STATUS_READY_BUSY_N_STATUS = {13, 0x1};
|
||||
bitmask MSM6800_STATUS_WRITE_PROTECT = {14, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_DONE = {15, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_ISLARGE = {16, 0x1};
|
||||
bitmask MSM6800_STATUS_NAND_AUTOPROBE_IS16BIT = {17, 0x1};
|
||||
bitmask MSM6800_STATUS_READ_ERROR = {31, 0x1};
|
||||
|
||||
bitmask MSM6800_COMMONCFG_BUFFER_MEM_WRITE_WAIT = {0, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_ECC_ERR_SELF_DETECT = {1, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_ECC_HALT_DIS = {2, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_CLK_HALT_DIS = {3, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_NAND_SEL = {4, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_DM_EN = {5, 0x1};
|
||||
bitmask MSM6800_COMMONCFG_NAND_AUTOPROBE = {6, 0x1};
|
||||
|
||||
bitmask MSM6800_FLASH_NAND_DEVID = {0, 0xff};
|
||||
bitmask MSM6800_FLASH_NAND_MFRID = {8, 0xff};
|
||||
bitmask MSM6800_FLASH_NAND_EXTID = {16, 0xff};
|
||||
|
||||
bitmask MSM6800_CONFIG1_ECC_DISABLED = {0, 0x1};
|
||||
bitmask MSM6800_CONFIG1_BUSFREE_SUPPORT_SELECT = {1, 0x1};
|
||||
bitmask MSM6800_CONFIG1_NAND_SIZE = {2, 0xf};
|
||||
bitmask MSM6800_CONFIG1_PAGE_IS_2KB = {6, 0x1};
|
||||
bitmask MSM6800_CONFIG1_WIDE_NAND = {7, 0x1};
|
||||
bitmask MSM6800_CONFIG1_NAND_RECOVERY_CYCLE = {8, 0x7};
|
||||
|
||||
bitmask MSM6800_CONFIG2_ID_RD_HOLD = {0, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_RD_HOLD = {5, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_RD_SETUP = {10, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_WR_HOLD = {15, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_WR_SETUP = {20, 0x1f};
|
||||
bitmask MSM6800_CONFIG2_WR_CS_SETUP = {25, 0x1f};
|
||||
|
|
@ -1,144 +1,144 @@
|
|||
// Qualcomm MSM7xxx NAND Controller
|
||||
// OneNAND is handled by the SFLASHC controller (msm7200.c in OneNAND folder)
|
||||
// https://github.com/chraso/GT-I5500_/blob/master/GT-I5500_OpenSource_Kernel/kernel/drivers/tfsr/PAM/MSM7k/FSR_PAM_MSM7k.c
|
||||
// https://github.com/mik9/ThunderG-Kernel/blob/7642626bcf53beeeef2632571015a43a6057e037/drivers/mtd/devices/msm_nand.c
|
||||
#include "../controller.h"
|
||||
#include "msm7200.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0xa0a00000
|
||||
#endif
|
||||
|
||||
#ifndef REGS_INIT1
|
||||
#define REGS_INIT1 0xaad400da
|
||||
#endif
|
||||
|
||||
#ifndef REGS_INIT2
|
||||
#define REGS_INIT2 0x44747c
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config_1;
|
||||
static uint32_t nand_config_2;
|
||||
|
||||
#define MSM7200_AUTOPROBE_CMD (4 << MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_AUTO_DETECT.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_LAST_PAGE.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_PAGE_ACC.bit_pos) | (MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ << MSM7200_NAND_FLASH_CMD_OP_CMD.bit_pos) // 0b100 1 1 1 0010 = 0x272
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_FLASH_CMD, cmd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_FLASH_STATUS, MSM7200_NAND_FLASH_STATUS_OPER_STATUS));
|
||||
}
|
||||
|
||||
void inline RunReadCommand(uint32_t addr1, uint32_t addr2, uint8_t subsequent) {
|
||||
wdog_reset();
|
||||
|
||||
if (!subsequent) {
|
||||
WRITE_U32(REGS_START + MSM7200_REG_FLASH_CMD, MSM7200_CMD_PAGE_READ_ALL);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, addr1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR1, addr2);
|
||||
}
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_FLASH_STATUS, MSM7200_NAND_FLASH_STATUS_OPER_STATUS));
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
nand_config_1 = REGS_INIT1;
|
||||
nand_config_2 = REGS_INIT2;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, nand_config_2);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD_VLD, 0xd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD0, 0x1080d060);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD1, 0xf00f3000);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD2, 0xf0ff7090);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD3, 0xf0ff7090);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD4, 0x800000);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD5, 0xf30094);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD6, 0x40e0);
|
||||
|
||||
RunCommand(MSM7200_CMD_RESET);
|
||||
RunCommand(MSM7200_CMD_RESET_NAND);
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, 0x0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR1, 0x0);
|
||||
|
||||
RunCommand(MSM7200_AUTOPROBE_CMD);
|
||||
if (GET_BIT32(REGS_START + MSM7200_REG_READ_STATUS, MSM7200_NAND_FLASH_STATUS_OP_ERR)) {
|
||||
return DCC_PROBE_ERROR;
|
||||
}
|
||||
|
||||
do { wdog_reset(); } while (!GET_BIT32(REGS_START + MSM7200_REG_READ_STATUS, MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE));
|
||||
|
||||
RunCommand(MSM7200_CMD_FETCH_ID);
|
||||
|
||||
uint32_t nand_idcode = READ_U32(REGS_START + MSM7200_REG_READ_ID);
|
||||
uint8_t mfr_id = (uint8_t)nand_idcode;
|
||||
uint8_t dev_id = (uint8_t)(nand_idcode >> 8);
|
||||
uint8_t ext_id = (uint8_t)(nand_idcode >> 24);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM7200_NAND_DEV_CFG0_CW_PER_PAGE, (mem->page_size >> 9) - 1);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_WIDE_FLASH, mem->bit_width >> 4);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA, mem->page_size <= 0x200);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM, mem->page_size <= 0x200 ? (mem->bit_width == 16 ? 1 : 6) : 0x1d1);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_ECC_DISABLE, 0);
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, nand_config_2);
|
||||
|
||||
RunCommand(MSM7200_CMD_RESET);
|
||||
RunCommand(MSM7200_CMD_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 9); i++) {
|
||||
RunReadCommand((mem->page_size > 0x200 ? page << 16 : page << 8), (mem->page_size > 0x200 ? page >> 16 : page >> 24), i > 0);
|
||||
PLAT_MEMCPY(page_buf + (i << 9), (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf + (i << 4), (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
// Qualcomm MSM7xxx NAND Controller
|
||||
// OneNAND is handled by the SFLASHC controller (msm7200.c in OneNAND folder)
|
||||
// https://github.com/chraso/GT-I5500_/blob/master/GT-I5500_OpenSource_Kernel/kernel/drivers/tfsr/PAM/MSM7k/FSR_PAM_MSM7k.c
|
||||
// https://github.com/mik9/ThunderG-Kernel/blob/7642626bcf53beeeef2632571015a43a6057e037/drivers/mtd/devices/msm_nand.c
|
||||
#include "../controller.h"
|
||||
#include "msm7200.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0xa0a00000
|
||||
#endif
|
||||
|
||||
#ifndef REGS_INIT1
|
||||
#define REGS_INIT1 0xaad400da
|
||||
#endif
|
||||
|
||||
#ifndef REGS_INIT2
|
||||
#define REGS_INIT2 0x44747c
|
||||
#endif
|
||||
|
||||
static uint32_t nand_config_1;
|
||||
static uint32_t nand_config_2;
|
||||
|
||||
#define MSM7200_AUTOPROBE_CMD (4 << MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_AUTO_DETECT.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_LAST_PAGE.bit_pos) | (1 << MSM7200_NAND_FLASH_CMD_PAGE_ACC.bit_pos) | (MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ << MSM7200_NAND_FLASH_CMD_OP_CMD.bit_pos) // 0b100 1 1 1 0010 = 0x272
|
||||
|
||||
void inline RunCommand(uint32_t cmd) {
|
||||
wdog_reset();
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_FLASH_CMD, cmd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_FLASH_STATUS, MSM7200_NAND_FLASH_STATUS_OPER_STATUS));
|
||||
}
|
||||
|
||||
void inline RunReadCommand(uint32_t addr1, uint32_t addr2, uint8_t subsequent) {
|
||||
wdog_reset();
|
||||
|
||||
if (!subsequent) {
|
||||
WRITE_U32(REGS_START + MSM7200_REG_FLASH_CMD, MSM7200_CMD_PAGE_READ_ALL);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, addr1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR1, addr2);
|
||||
}
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_FLASH_STATUS, MSM7200_NAND_FLASH_STATUS_OPER_STATUS));
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
nand_config_1 = REGS_INIT1;
|
||||
nand_config_2 = REGS_INIT2;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, nand_config_2);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD_VLD, 0xd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD0, 0x1080d060);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD1, 0xf00f3000);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD2, 0xf0ff7090);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD3, 0xf0ff7090);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD4, 0x800000);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD5, 0xf30094);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD6, 0x40e0);
|
||||
|
||||
RunCommand(MSM7200_CMD_RESET);
|
||||
RunCommand(MSM7200_CMD_RESET_NAND);
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, 0x0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR1, 0x0);
|
||||
|
||||
RunCommand(MSM7200_AUTOPROBE_CMD);
|
||||
if (GET_BIT32(REGS_START + MSM7200_REG_READ_STATUS, MSM7200_NAND_FLASH_STATUS_OP_ERR)) {
|
||||
return DCC_PROBE_ERROR;
|
||||
}
|
||||
|
||||
do { wdog_reset(); } while (!GET_BIT32(REGS_START + MSM7200_REG_READ_STATUS, MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE));
|
||||
|
||||
RunCommand(MSM7200_CMD_FETCH_ID);
|
||||
|
||||
uint32_t nand_idcode = READ_U32(REGS_START + MSM7200_REG_READ_ID);
|
||||
uint8_t mfr_id = (uint8_t)nand_idcode;
|
||||
uint8_t dev_id = (uint8_t)(nand_idcode >> 8);
|
||||
uint8_t ext_id = (uint8_t)(nand_idcode >> 24);
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint8_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = (uint16_t)dev_id;
|
||||
mem->manufacturer = (uint16_t)mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
mem->page_size = 1 << (10 + (ext_id & 3));
|
||||
|
||||
switch ((ext_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= ext_id << 8;
|
||||
}
|
||||
|
||||
BIT_SET_VAR(nand_config_1, MSM7200_NAND_DEV_CFG0_CW_PER_PAGE, (mem->page_size >> 9) - 1);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_WIDE_FLASH, mem->bit_width >> 4);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA, mem->page_size <= 0x200);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM, mem->page_size <= 0x200 ? (mem->bit_width == 16 ? 1 : 6) : 0x1d1);
|
||||
BIT_SET_VAR(nand_config_2, MSM7200_NAND_DEV_CFG1_ECC_DISABLE, 0);
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, nand_config_1);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, nand_config_2);
|
||||
|
||||
RunCommand(MSM7200_CMD_RESET);
|
||||
RunCommand(MSM7200_CMD_RESET_NAND);
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> 9); i++) {
|
||||
RunReadCommand((mem->page_size > 0x200 ? page << 16 : page << 8), (mem->page_size > 0x200 ? page >> 16 : page >> 24), i > 0);
|
||||
PLAT_MEMCPY(page_buf + (i << 9), (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER), 0x200);
|
||||
PLAT_MEMCPY(spare_buf + (i << 4), (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER + 0x200), 0x10);
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,343 +1,343 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM7200_REG_FLASH_CMD 0x0000
|
||||
#define MSM7200_REG_ADDR0 0x0004
|
||||
#define MSM7200_REG_ADDR1 0x0008
|
||||
#define MSM7200_REG_FLASH_CHIP_SELECT 0x000C
|
||||
#define MSM7200_REG_EXEC_CMD 0x0010
|
||||
#define MSM7200_REG_FLASH_STATUS 0x0014
|
||||
#define MSM7200_REG_BUFFER_STATUS 0x0018
|
||||
#define MSM7200_REG_SFLASHC_STATUS 0x001C
|
||||
#define MSM7200_REG_DEV0_CFG0 0x0020
|
||||
#define MSM7200_REG_DEV0_CFG1 0x0024
|
||||
#define MSM7200_REG_DEV0_ECC_CFG 0x0028
|
||||
#define MSM7200_REG_DEV1_ECC_CFG 0x002C
|
||||
#define MSM7200_REG_DEV1_CFG0 0x0030
|
||||
#define MSM7200_REG_DEV1_CFG1 0x0034
|
||||
#define MSM7200_REG_SFLASHC_CMD 0x0038
|
||||
#define MSM7200_REG_SFLASHC_EXEC_CMD 0x003C
|
||||
#define MSM7200_REG_READ_ID 0x0040
|
||||
#define MSM7200_REG_READ_STATUS 0x0044
|
||||
#define MSM7200_REG_CONFIG_DATA 0x0050
|
||||
#define MSM7200_REG_CONFIG 0x0054
|
||||
#define MSM7200_REG_CONFIG_MODE 0x0058
|
||||
#define MSM7200_REG_CONFIG_STATUS 0x0060
|
||||
#define MSM7200_REG_MACRO1_REG 0x0064
|
||||
#define MSM7200_REG_XFR_STEP1 0x0070
|
||||
#define MSM7200_REG_XFR_STEP2 0x0074
|
||||
#define MSM7200_REG_XFR_STEP3 0x0078
|
||||
#define MSM7200_REG_XFR_STEP4 0x007C
|
||||
#define MSM7200_REG_XFR_STEP5 0x0080
|
||||
#define MSM7200_REG_XFR_STEP6 0x0084
|
||||
#define MSM7200_REG_XFR_STEP7 0x0088
|
||||
#define MSM7200_REG_GENP_REG0 0x0090
|
||||
#define MSM7200_REG_GENP_REG1 0x0094
|
||||
#define MSM7200_REG_GENP_REG2 0x0098
|
||||
#define MSM7200_REG_GENP_REG3 0x009C
|
||||
#define MSM7200_REG_DEV_CMD0 0x00A0
|
||||
#define MSM7200_REG_DEV_CMD1 0x00A4
|
||||
#define MSM7200_REG_DEV_CMD2 0x00A8
|
||||
#define MSM7200_REG_DEV_CMD_VLD 0x00AC
|
||||
#define MSM7200_REG_EBI2_MISR_SIG_REG 0x00B0
|
||||
#define MSM7200_REG_ADDR2 0x00C0
|
||||
#define MSM7200_REG_ADDR3 0x00C4
|
||||
#define MSM7200_REG_ADDR4 0x00C8
|
||||
#define MSM7200_REG_ADDR5 0x00CC
|
||||
#define MSM7200_REG_DEV_CMD3 0x00D0
|
||||
#define MSM7200_REG_DEV_CMD4 0x00D4
|
||||
#define MSM7200_REG_DEV_CMD5 0x00D8
|
||||
#define MSM7200_REG_DEV_CMD6 0x00DC
|
||||
#define MSM7200_REG_SFLASHC_BURST_CFG 0x00E0
|
||||
#define MSM7200_REG_ADDR6 0x00E4
|
||||
#define MSM7200_REG_EBI2_ECC_BUF_CFG 0x00F0
|
||||
#define MSM7200_REG_HW_INFO 0x00FC
|
||||
#define MSM7200_REG_FLASH_BUFFER 0x0100
|
||||
#define MSM7200_REG_NAND_MPU_ENABLE 0x100000
|
||||
|
||||
#define MSM7200_CMD_RESET 0x31
|
||||
#define MSM7200_CMD_PAGE_READ 0x32
|
||||
#define MSM7200_CMD_PAGE_READ_ECC 0x33
|
||||
#define MSM7200_CMD_PAGE_READ_ALL 0x34
|
||||
#define MSM7200_CMD_SEQ_PAGE_READ 0x15
|
||||
#define MSM7200_CMD_PRG_PAGE 0x36
|
||||
#define MSM7200_CMD_PRG_PAGE_ECC 0x37
|
||||
#define MSM7200_CMD_PRG_PAGE_ALL 0x39
|
||||
#define MSM7200_CMD_BLOCK_ERASE 0x3A
|
||||
#define MSM7200_CMD_FETCH_ID 0x0B
|
||||
#define MSM7200_CMD_STATUS 0x0C
|
||||
#define MSM7200_CMD_RESET_NAND 0x0D
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_LAST = {26, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_SEQ = {25, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_READ_CACHE_NEXT_CMD = {24, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_PROGRAM_PAGE_CACHE_NEXT_CMD = {20, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EXTENDED_FETCH_ID = {19, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_INTR_STATUS = {18, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_HOST_CFG = {17, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE = {7, 0x3ff};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_LAST_PAGE = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_PAGE_ACC = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_OP_CMD = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_NON_PAGE_ACCESS_COMMAND 0
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_PAGE_ACCESS_COMMAND 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_0 0
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC_SPARE 4
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_PROGRAM_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_8 8
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESET_NAND_FLASH_DEVICE_OR_ONENAND_REGISTER_WRITE 13
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_E 14
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_F 15
|
||||
|
||||
bitmask MSM7200_NAND_ADDR0_DEV_ADDR0 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR1_DEV_ADDR1 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_RESET_XFR_STEP_LOAD_DONE_STATUS = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_ONE_NAND_EN = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_DM_EN = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN_DYNAMICALLY_CHANGING_THE_XFR_STEP2_IS_ENABLED 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_DISABLE 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_ENABLE 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS0_IS_SELECTED 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS1_IS_SELECTED 1
|
||||
|
||||
bitmask MSM7200_NANDC_EXEC_CMD_EXEC_CMD = {0, 0x1};
|
||||
#define MSM7200_NANDC_EXEC_CMD_EXEC_CMD_EXECUTE_THE_COMMAND 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_DEV_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_CODEWORD_CNTR = {12, 0xf};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE = {11, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE = {10, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_MPU_ERROR = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_PROG_ERASE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_READY_BSY_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OP_ERR = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OPER_STATUS = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_NOT_A_2K_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_ENUM_2K_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_NOT_A_512_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_ENUM_512_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_MPU_ERROR_FOR_THE_ACCESS 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_ERROR 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_BUSY 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_READY 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_IDLE_STATE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC_AND_SPARE_DATA 4
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_SEQUENTIAL_PAGE_READ 5
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESERVED_PROGRAMMING 8
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESET_FLASH_DEVICE 13
|
||||
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_BAD_BLOCK_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_XFR_STEP2_REG_UPDATE_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_UNCORRECTABLE = {8, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_NUM_ERRORS = {0, 0x1f};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SET_RD_MODE_AFTER_STATUS = {31, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_STATUS_BFR_READ = {30, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES = {27, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SPARE_SIZE_BYTES = {23, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ECC_PARITY_SIZE_BYTES = {19, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_UD_SIZE_BYTES = {9, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_CW_PER_PAGE = {6, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES = {3, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES = {0, 0x7};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES_NO_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__1_CODEWORD_PER_PAGE 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__2_CODEWORDS_PER_PAGE 1
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__3_CODEWORDS_PER_PAGE 2
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__4_CODEWORDS_PER_PAGE 3
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__5_CODEWORDS_PER_PAGE 4
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__6_CODEWORDS_PER_PAGE 5
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__7_CODEWORDS_PER_PAGE 6
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__8_CODEWORDS_PER_PAGE 7
|
||||
#define MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES_NO_ROW_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES_NO_COLUMN_ADDRESS_CYCLES 0
|
||||
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_MODE = {28, 0x3};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ENABLE_BCH_ECC = {27, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_DISABLE_ECC_RESET_AFTER_OPDONE = {25, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DECODER_CGC_EN = {24, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_ENCODER_CGC_EN = {23, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP = {17, 0x3f};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA = {16, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM = {6, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY = {5, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES = {2, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WIDE_FLASH = {1, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DISABLE = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_2_CLOCK_CYCLE_GAP 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_4_CLOCK_CYCLES_GAP 1
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_6_CLOCK_CYCLES_GAP 2
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_8_CLOCK_CYCLES_GAP 3
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_10_CLOCK_CYCLES_GAP 4
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_128_CLOCK_CYCLES_GAP 63
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_USER_DATA_AREA 0
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_SPARE_AREA 1
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ALLOW_CS_DE_ASSERTION 0
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ASSERT_CS_DURING_BUSY 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_1_RECOVERY_CYCLE 0
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_2_RECOVERY_CYCLES 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_3_RECOVERY_CYCLES 2
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_8_RECOVERY_CYCLES 7
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_8_BIT_DATA_BUS 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_16_BIT_DATA_BUS 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_READ_ID_READ_ID = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_ECC_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_DEV_STATUS = {0, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_DATA_IN = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ADDR_OUT = {14, 0x3};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT_EN = {13, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN = {10, 0x7};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS5_N = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS4_N = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS3_N = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS2_N = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS1_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS0_N = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ALE = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CLE = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_WE_N = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_RE_N = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_DONT_READ 0
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_15_0 1
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_31_16 2
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_READ_STATUS_15_0 3
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_MODE_CONFIG_ACC = {0, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_STATUS_CONFIG_MODE = {0, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_ADDR_BUS_HOLD_CYCLE = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_DATA_START_ADDR = {0, 0xffff};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO1 = {14, 0x3f};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO0 = {0, 0x3fff};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER = {30, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_STEP1_WAIT = {26, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN = {25, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_DATA_EN = {24, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CE_EN = {23, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CLE_EN = {22, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN = {21, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WE_EN = {20, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_RE_EN = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WIDE = {18, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER = {14, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_STEP1_WAIT = {10, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN = {9, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_DATA_EN = {8, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CE_EN = {7, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CLE_EN = {6, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN = {5, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WE_EN = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_RE_EN = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WIDE = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_EXTA_READ_WAIT = {0, 0x3};
|
||||
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_SIMPLE_STEP 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_8_BIT_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_16_BIT_BUS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE_8_BIT_DATA_BUS_FOR_DATA 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE16_BIT_DATA_BUS_FOR_DATA 1
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_START = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_ADDR = {16, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_START = {8, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_ADDR = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_PARAMETER_PAGE_CODE = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_SEQ_READ_START_VLD = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_ERASE_START_VLD = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_WRITE_START_VLD = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_STOP_VLD = {1, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_START_VLD = {0, 0x1};
|
||||
|
||||
bitmask MSM7200_EBI2_MISR_SIG_REG_EBI2_MISR_SIG = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR2_DEV_ADDR2 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR3_DEV_ADDR3 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR4_DEV_ADDR4 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR5_DEV_ADDR5 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_LAST = {24, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_SEQ = {16, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_WRITE_START_CACHE = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD4 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD3 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD6 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD5 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD8 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD7 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR6_DEV_ADDR6 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_EBI2_ECC_BUF_CFG_NUM_STEPS = {0, 0x3ff};
|
||||
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM7200_REG_FLASH_CMD 0x0000
|
||||
#define MSM7200_REG_ADDR0 0x0004
|
||||
#define MSM7200_REG_ADDR1 0x0008
|
||||
#define MSM7200_REG_FLASH_CHIP_SELECT 0x000C
|
||||
#define MSM7200_REG_EXEC_CMD 0x0010
|
||||
#define MSM7200_REG_FLASH_STATUS 0x0014
|
||||
#define MSM7200_REG_BUFFER_STATUS 0x0018
|
||||
#define MSM7200_REG_SFLASHC_STATUS 0x001C
|
||||
#define MSM7200_REG_DEV0_CFG0 0x0020
|
||||
#define MSM7200_REG_DEV0_CFG1 0x0024
|
||||
#define MSM7200_REG_DEV0_ECC_CFG 0x0028
|
||||
#define MSM7200_REG_DEV1_ECC_CFG 0x002C
|
||||
#define MSM7200_REG_DEV1_CFG0 0x0030
|
||||
#define MSM7200_REG_DEV1_CFG1 0x0034
|
||||
#define MSM7200_REG_SFLASHC_CMD 0x0038
|
||||
#define MSM7200_REG_SFLASHC_EXEC_CMD 0x003C
|
||||
#define MSM7200_REG_READ_ID 0x0040
|
||||
#define MSM7200_REG_READ_STATUS 0x0044
|
||||
#define MSM7200_REG_CONFIG_DATA 0x0050
|
||||
#define MSM7200_REG_CONFIG 0x0054
|
||||
#define MSM7200_REG_CONFIG_MODE 0x0058
|
||||
#define MSM7200_REG_CONFIG_STATUS 0x0060
|
||||
#define MSM7200_REG_MACRO1_REG 0x0064
|
||||
#define MSM7200_REG_XFR_STEP1 0x0070
|
||||
#define MSM7200_REG_XFR_STEP2 0x0074
|
||||
#define MSM7200_REG_XFR_STEP3 0x0078
|
||||
#define MSM7200_REG_XFR_STEP4 0x007C
|
||||
#define MSM7200_REG_XFR_STEP5 0x0080
|
||||
#define MSM7200_REG_XFR_STEP6 0x0084
|
||||
#define MSM7200_REG_XFR_STEP7 0x0088
|
||||
#define MSM7200_REG_GENP_REG0 0x0090
|
||||
#define MSM7200_REG_GENP_REG1 0x0094
|
||||
#define MSM7200_REG_GENP_REG2 0x0098
|
||||
#define MSM7200_REG_GENP_REG3 0x009C
|
||||
#define MSM7200_REG_DEV_CMD0 0x00A0
|
||||
#define MSM7200_REG_DEV_CMD1 0x00A4
|
||||
#define MSM7200_REG_DEV_CMD2 0x00A8
|
||||
#define MSM7200_REG_DEV_CMD_VLD 0x00AC
|
||||
#define MSM7200_REG_EBI2_MISR_SIG_REG 0x00B0
|
||||
#define MSM7200_REG_ADDR2 0x00C0
|
||||
#define MSM7200_REG_ADDR3 0x00C4
|
||||
#define MSM7200_REG_ADDR4 0x00C8
|
||||
#define MSM7200_REG_ADDR5 0x00CC
|
||||
#define MSM7200_REG_DEV_CMD3 0x00D0
|
||||
#define MSM7200_REG_DEV_CMD4 0x00D4
|
||||
#define MSM7200_REG_DEV_CMD5 0x00D8
|
||||
#define MSM7200_REG_DEV_CMD6 0x00DC
|
||||
#define MSM7200_REG_SFLASHC_BURST_CFG 0x00E0
|
||||
#define MSM7200_REG_ADDR6 0x00E4
|
||||
#define MSM7200_REG_EBI2_ECC_BUF_CFG 0x00F0
|
||||
#define MSM7200_REG_HW_INFO 0x00FC
|
||||
#define MSM7200_REG_FLASH_BUFFER 0x0100
|
||||
#define MSM7200_REG_NAND_MPU_ENABLE 0x100000
|
||||
|
||||
#define MSM7200_CMD_RESET 0x31
|
||||
#define MSM7200_CMD_PAGE_READ 0x32
|
||||
#define MSM7200_CMD_PAGE_READ_ECC 0x33
|
||||
#define MSM7200_CMD_PAGE_READ_ALL 0x34
|
||||
#define MSM7200_CMD_SEQ_PAGE_READ 0x15
|
||||
#define MSM7200_CMD_PRG_PAGE 0x36
|
||||
#define MSM7200_CMD_PRG_PAGE_ECC 0x37
|
||||
#define MSM7200_CMD_PRG_PAGE_ALL 0x39
|
||||
#define MSM7200_CMD_BLOCK_ERASE 0x3A
|
||||
#define MSM7200_CMD_FETCH_ID 0x0B
|
||||
#define MSM7200_CMD_STATUS 0x0C
|
||||
#define MSM7200_CMD_RESET_NAND 0x0D
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_LAST = {26, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_SEQ = {25, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_READ_CACHE_NEXT_CMD = {24, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_PROGRAM_PAGE_CACHE_NEXT_CMD = {20, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EXTENDED_FETCH_ID = {19, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_INTR_STATUS = {18, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_HOST_CFG = {17, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE = {7, 0x3ff};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_LAST_PAGE = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_PAGE_ACC = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_OP_CMD = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_NON_PAGE_ACCESS_COMMAND 0
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_PAGE_ACCESS_COMMAND 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_0 0
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC_SPARE 4
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_PROGRAM_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_8 8
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESET_NAND_FLASH_DEVICE_OR_ONENAND_REGISTER_WRITE 13
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_E 14
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_F 15
|
||||
|
||||
bitmask MSM7200_NAND_ADDR0_DEV_ADDR0 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR1_DEV_ADDR1 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_RESET_XFR_STEP_LOAD_DONE_STATUS = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_ONE_NAND_EN = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_DM_EN = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN_DYNAMICALLY_CHANGING_THE_XFR_STEP2_IS_ENABLED 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_DISABLE 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_ENABLE 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS0_IS_SELECTED 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS1_IS_SELECTED 1
|
||||
|
||||
bitmask MSM7200_NANDC_EXEC_CMD_EXEC_CMD = {0, 0x1};
|
||||
#define MSM7200_NANDC_EXEC_CMD_EXEC_CMD_EXECUTE_THE_COMMAND 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_DEV_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_CODEWORD_CNTR = {12, 0xf};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE = {11, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE = {10, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_MPU_ERROR = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_PROG_ERASE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_READY_BSY_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OP_ERR = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OPER_STATUS = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_NOT_A_2K_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_ENUM_2K_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_NOT_A_512_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_ENUM_512_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_MPU_ERROR_FOR_THE_ACCESS 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_ERROR 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_BUSY 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_READY 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_IDLE_STATE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC_AND_SPARE_DATA 4
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_SEQUENTIAL_PAGE_READ 5
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESERVED_PROGRAMMING 8
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESET_FLASH_DEVICE 13
|
||||
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_BAD_BLOCK_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_XFR_STEP2_REG_UPDATE_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_UNCORRECTABLE = {8, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_NUM_ERRORS = {0, 0x1f};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SET_RD_MODE_AFTER_STATUS = {31, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_STATUS_BFR_READ = {30, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES = {27, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SPARE_SIZE_BYTES = {23, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ECC_PARITY_SIZE_BYTES = {19, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_UD_SIZE_BYTES = {9, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_CW_PER_PAGE = {6, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES = {3, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES = {0, 0x7};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES_NO_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__1_CODEWORD_PER_PAGE 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__2_CODEWORDS_PER_PAGE 1
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__3_CODEWORDS_PER_PAGE 2
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__4_CODEWORDS_PER_PAGE 3
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__5_CODEWORDS_PER_PAGE 4
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__6_CODEWORDS_PER_PAGE 5
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__7_CODEWORDS_PER_PAGE 6
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__8_CODEWORDS_PER_PAGE 7
|
||||
#define MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES_NO_ROW_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES_NO_COLUMN_ADDRESS_CYCLES 0
|
||||
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_MODE = {28, 0x3};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ENABLE_BCH_ECC = {27, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_DISABLE_ECC_RESET_AFTER_OPDONE = {25, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DECODER_CGC_EN = {24, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_ENCODER_CGC_EN = {23, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP = {17, 0x3f};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA = {16, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM = {6, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY = {5, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES = {2, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WIDE_FLASH = {1, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DISABLE = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_2_CLOCK_CYCLE_GAP 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_4_CLOCK_CYCLES_GAP 1
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_6_CLOCK_CYCLES_GAP 2
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_8_CLOCK_CYCLES_GAP 3
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_10_CLOCK_CYCLES_GAP 4
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_128_CLOCK_CYCLES_GAP 63
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_USER_DATA_AREA 0
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_SPARE_AREA 1
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ALLOW_CS_DE_ASSERTION 0
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ASSERT_CS_DURING_BUSY 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_1_RECOVERY_CYCLE 0
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_2_RECOVERY_CYCLES 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_3_RECOVERY_CYCLES 2
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_8_RECOVERY_CYCLES 7
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_8_BIT_DATA_BUS 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_16_BIT_DATA_BUS 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_READ_ID_READ_ID = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_ECC_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_DEV_STATUS = {0, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_DATA_IN = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ADDR_OUT = {14, 0x3};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT_EN = {13, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN = {10, 0x7};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS5_N = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS4_N = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS3_N = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS2_N = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS1_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS0_N = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ALE = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CLE = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_WE_N = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_RE_N = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_DONT_READ 0
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_15_0 1
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_31_16 2
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_READ_STATUS_15_0 3
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_MODE_CONFIG_ACC = {0, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_STATUS_CONFIG_MODE = {0, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_ADDR_BUS_HOLD_CYCLE = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_DATA_START_ADDR = {0, 0xffff};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO1 = {14, 0x3f};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO0 = {0, 0x3fff};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER = {30, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_STEP1_WAIT = {26, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN = {25, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_DATA_EN = {24, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CE_EN = {23, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CLE_EN = {22, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN = {21, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WE_EN = {20, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_RE_EN = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WIDE = {18, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER = {14, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_STEP1_WAIT = {10, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN = {9, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_DATA_EN = {8, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CE_EN = {7, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CLE_EN = {6, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN = {5, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WE_EN = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_RE_EN = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WIDE = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_EXTA_READ_WAIT = {0, 0x3};
|
||||
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_SIMPLE_STEP 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_8_BIT_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_16_BIT_BUS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE_8_BIT_DATA_BUS_FOR_DATA 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE16_BIT_DATA_BUS_FOR_DATA 1
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_START = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_ADDR = {16, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_START = {8, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_ADDR = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_PARAMETER_PAGE_CODE = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_SEQ_READ_START_VLD = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_ERASE_START_VLD = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_WRITE_START_VLD = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_STOP_VLD = {1, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_START_VLD = {0, 0x1};
|
||||
|
||||
bitmask MSM7200_EBI2_MISR_SIG_REG_EBI2_MISR_SIG = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR2_DEV_ADDR2 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR3_DEV_ADDR3 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR4_DEV_ADDR4 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR5_DEV_ADDR5 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_LAST = {24, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_SEQ = {16, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_WRITE_START_CACHE = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD4 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD3 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD6 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD5 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD8 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD7 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR6_DEV_ADDR6 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_EBI2_ECC_BUF_CFG_NUM_STEPS = {0, 0x3ff};
|
||||
|
||||
bitmask MSM7200_FLASH_BUFF0_ACC_BUFF_DATA = {0, 0xffffffff};
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#define REGS_START 0x80008000
|
||||
|
||||
#define REGS_START 0x80008000
|
||||
|
||||
#include "msm7200.c"
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#define REGS_START 0x64000000
|
||||
#define INTERRUPT_WRITE 0x80000C84
|
||||
#define INTERRUPT_READ 0x80000C84
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#define REGS_START 0x64000000
|
||||
#define INTERRUPT_WRITE 0x80000C84
|
||||
#define INTERRUPT_READ 0x80000C84
|
||||
#define INTERRUPT_CLEAR_VALUE 0x6000
|
||||
#define INTERRUPT_ASSERT_VALUE 0x2000
|
||||
|
||||
#include "msm6800.c"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#define REGS_START 0x70000000
|
||||
|
||||
#define REGS_START 0x70000000
|
||||
|
||||
#include "msm7200.c"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#define REGS_START 0x60008000
|
||||
#define REGS_INIT1 0xaad4001a
|
||||
#define REGS_INIT2 0x44747e
|
||||
// OneNAND is handled by default onenand controller at 0x38000000 (Must not set NAND_BUS_ENA at EBI2_CFG; 0x80028000, Corresponds to EBI2_CS0_N)
|
||||
|
||||
#define REGS_START 0x60008000
|
||||
#define REGS_INIT1 0xaad4001a
|
||||
#define REGS_INIT2 0x44747e
|
||||
// OneNAND is handled by default onenand controller at 0x38000000 (Must not set NAND_BUS_ENA at EBI2_CFG; 0x80028000, Corresponds to EBI2_CS0_N)
|
||||
|
||||
#include "msm7200.c"
|
||||
|
|
@ -1,254 +1,254 @@
|
|||
/* Samsung S3C2410 NAND Controller */
|
||||
#include "../controller.h"
|
||||
#include "s3c2410.h"
|
||||
|
||||
#ifndef NAND_BASE
|
||||
#define NAND_BASE 0x4e000000
|
||||
#endif
|
||||
|
||||
#ifndef NAND_SYS_TYPE
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2410
|
||||
#endif
|
||||
|
||||
static uint8_t bit_width;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
WRITE_U16(NAND_BASE + S3C2410_NFCMD, (uint16_t)cmd);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
WRITE_U16(NAND_BASE + S3C2440_2412_NFCMD, (uint16_t)cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
WRITE_U16(NAND_BASE + S3C2410_NFADDR, (uint16_t)addr);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
WRITE_U16(NAND_BASE + S3C2440_2412_NFADDR, (uint16_t)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
return bit_width == 16 ? READ_U16(NAND_BASE + S3C2410_NFDATA) : READ_U8(NAND_BASE + S3C2410_NFDATA);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
return bit_width == 16 ? READ_U16(NAND_BASE + S3C2440_2412_NFDATA) : READ_U8(NAND_BASE + S3C2440_2412_NFDATA);
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2410_NFSTAT, S3C2410_NFSTAT_BUSY));
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2440_NFSTAT, S3C2440_NFSTAT_READY));
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2412_NFSTAT, S3C2412_NFSTAT_READY));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
uint32_t NFCONF = 0;
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_EN, 1);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_INITECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_NFCE, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH0, 5);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH1, 3);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
uint32_t NFCONT = 0;
|
||||
|
||||
BIT_SET_VAR(NFCONT, S3C2440_2412_NFCONT_ENABLE, 1);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_NFCE, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_INITECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TWRPH0, 7);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TWRPH1, 7);
|
||||
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
uint32_t NFCONT = 0;
|
||||
|
||||
BIT_SET_VAR(NFCONT, S3C2440_2412_NFCONT_ENABLE, 1);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_nFCE0, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_nFCE1, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_MAIN_ECC, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_SECONDARY_ECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH0, 7);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH1, 7);
|
||||
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#endif
|
||||
WRITE_U32(NAND_BASE + S3C2410_2440_2412_NFCONF, NFCONF);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
#else
|
||||
// Not supported by HW
|
||||
mem->type = MEMTYPE_NONE;
|
||||
return DCC_PROBE_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
bit_width = mem->bit_width;
|
||||
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_INITECC, 1);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_BUSWIDTH, bit_width == 16 ? 1 : 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_INITECC, 1);
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_BUSWIDTH, bit_width == 16 ? 1 : 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_MAIN_ECC, 1);
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#endif
|
||||
WRITE_U32(NAND_BASE + S3C2410_2440_2412_NFCONF, NFCONF);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
/* Samsung S3C2410 NAND Controller */
|
||||
#include "../controller.h"
|
||||
#include "s3c2410.h"
|
||||
|
||||
#ifndef NAND_BASE
|
||||
#define NAND_BASE 0x4e000000
|
||||
#endif
|
||||
|
||||
#ifndef NAND_SYS_TYPE
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2410
|
||||
#endif
|
||||
|
||||
static uint8_t bit_width;
|
||||
|
||||
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
WRITE_U16(NAND_BASE + S3C2410_NFCMD, (uint16_t)cmd);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
WRITE_U16(NAND_BASE + S3C2440_2412_NFCMD, (uint16_t)cmd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
WRITE_U16(NAND_BASE + S3C2410_NFADDR, (uint16_t)addr);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
WRITE_U16(NAND_BASE + S3C2440_2412_NFADDR, (uint16_t)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t inline NAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
return bit_width == 16 ? READ_U16(NAND_BASE + S3C2410_NFDATA) : READ_U8(NAND_BASE + S3C2410_NFDATA);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
return bit_width == 16 ? READ_U16(NAND_BASE + S3C2440_2412_NFDATA) : READ_U8(NAND_BASE + S3C2440_2412_NFDATA);
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline NAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2410_NFSTAT, S3C2410_NFSTAT_BUSY));
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2440_NFSTAT, S3C2440_NFSTAT_READY));
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
do { wdog_reset(); } while (!GET_BIT8(NAND_BASE + S3C2412_NFSTAT, S3C2412_NFSTAT_READY));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t inline NAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
uint32_t NFCONF = 0;
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_EN, 1);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_INITECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_NFCE, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH0, 5);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH1, 3);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
uint32_t NFCONT = 0;
|
||||
|
||||
BIT_SET_VAR(NFCONT, S3C2440_2412_NFCONT_ENABLE, 1);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_NFCE, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_INITECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TWRPH0, 7);
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_TWRPH1, 7);
|
||||
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
uint32_t NFCONT = 0;
|
||||
|
||||
BIT_SET_VAR(NFCONT, S3C2440_2412_NFCONT_ENABLE, 1);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_nFCE0, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_nFCE1, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_MAIN_ECC, 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_SECONDARY_ECC, 0);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TACLS, 3);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH0, 7);
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_TWRPH1, 7);
|
||||
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#endif
|
||||
WRITE_U32(NAND_BASE + S3C2410_2440_2412_NFCONF, NFCONF);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READID);
|
||||
NAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = NAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = NAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_NAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_NAND) return DCC_PROBE_ERROR;
|
||||
|
||||
if (mem->page_size == 0) {
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2440 || NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
NAND_Ctrl_Data_Read();
|
||||
uint8_t extra_id = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
|
||||
mem->page_size = 1 << (10 + (extra_id & 3));
|
||||
|
||||
switch ((extra_id >> 4) & 3) {
|
||||
case 0:
|
||||
mem->block_size = 64 << 10;
|
||||
break;
|
||||
case 1:
|
||||
mem->block_size = 128 << 10;
|
||||
break;
|
||||
case 2:
|
||||
mem->block_size = 256 << 10;
|
||||
break;
|
||||
case 3:
|
||||
mem->block_size = 512 << 10;
|
||||
break;
|
||||
}
|
||||
|
||||
mem->device_id |= extra_id << 8;
|
||||
#else
|
||||
// Not supported by HW
|
||||
mem->type = MEMTYPE_NONE;
|
||||
return DCC_PROBE_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
bit_width = mem->bit_width;
|
||||
|
||||
#if NAND_SYS_TYPE == SYSTYPE_S3C2410
|
||||
BIT_SET_VAR(NFCONF, S3C2410_NFCONF_INITECC, 1);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2440
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_BUSWIDTH, bit_width == 16 ? 1 : 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2440_NFCONT_INITECC, 1);
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#elif NAND_SYS_TYPE == SYSTYPE_S3C2412
|
||||
BIT_SET_VAR(NFCONF, S3C2440_2412_NFCONF_BUSWIDTH, bit_width == 16 ? 1 : 0);
|
||||
BIT_SET_VAR(NFCONT, S3C2412_NFCONT_INIT_MAIN_ECC, 1);
|
||||
WRITE_U32(NAND_BASE + S3C2440_2412_NFCONT, NFCONT);
|
||||
#endif
|
||||
WRITE_U32(NAND_BASE + S3C2410_2440_2412_NFCONF, NFCONF);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
if (mem->page_size <= 512) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->bit_width == 8) {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ1);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
wdog_reset();
|
||||
page_buf[i + 0x100] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READOOB);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x02000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (0x10 >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READ0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(0);
|
||||
NAND_Ctrl_Address_Write(page);
|
||||
NAND_Ctrl_Address_Write(page >> 8);
|
||||
if (mem->size > 0x08000000) NAND_Ctrl_Address_Write(page >> 16);
|
||||
|
||||
NAND_Ctrl_Command_Write(NAND_CMD_READSTART);
|
||||
NAND_Ctrl_Wait_Ready();
|
||||
if (!NAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ((mem->page_size >> 5) >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(spare_buf))[i] = NAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
spare_buf[i] = (uint8_t)NAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,103 +1,103 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define SYSTYPE_S3C2410 0
|
||||
#define SYSTYPE_S3C2440 1
|
||||
#define SYSTYPE_S3C2412 2
|
||||
|
||||
/* Common */
|
||||
#define S3C2410_2440_2412_NFCONF 0x00
|
||||
|
||||
/* S3C2410 */
|
||||
#define S3C2410_NFCMD 0x04
|
||||
#define S3C2410_NFADDR 0x08
|
||||
#define S3C2410_NFDATA 0x0C
|
||||
#define S3C2410_NFSTAT 0x10
|
||||
#define S3C2410_NFECC 0x14
|
||||
|
||||
/* S3C2440 */
|
||||
#define S3C2440_2412_NFCONT 0x04
|
||||
#define S3C2440_2412_NFCMD 0x08
|
||||
#define S3C2440_2412_NFADDR 0x0C
|
||||
#define S3C2440_2412_NFDATA 0x10
|
||||
#define S3C2440_2412_NFECCD0 0x14
|
||||
#define S3C2440_2412_NFECCD1 0x18
|
||||
#define S3C2440_2412_NFECCD 0x1C
|
||||
#define S3C2440_NFSTAT 0x20
|
||||
#define S3C2440_NFESTAT0 0x24
|
||||
#define S3C2440_NFESTAT1 0x28
|
||||
#define S3C2440_NFMECC0 0x2C
|
||||
#define S3C2440_NFMECC1 0x30
|
||||
#define S3C2440_NFSECC 0x34
|
||||
#define S3C2440_NFSBLK 0x38
|
||||
#define S3C2440_NFEBLK 0x3C
|
||||
|
||||
/* S3C2412 */
|
||||
#define S3C2412_NFSBLK 0x20
|
||||
#define S3C2412_NFEBLK 0x24
|
||||
#define S3C2412_NFSTAT 0x28
|
||||
#define S3C2412_NFMECC_ERR0 0x2C
|
||||
#define S3C2412_NFMECC_ERR1 0x30
|
||||
#define S3C2412_NFMECC0 0x34
|
||||
#define S3C2412_NFMECC1 0x38
|
||||
#define S3C2412_NFSECC 0x3C
|
||||
|
||||
/* S3C2410 bits */
|
||||
bitmask S3C2410_NFCONF_EN = {15, 0x1};
|
||||
bitmask S3C2410_NFCONF_INITECC = {12, 0x1};
|
||||
bitmask S3C2410_NFCONF_NFCE = {11, 0x1};
|
||||
bitmask S3C2410_NFCONF_TACLS = {8, 0x7};
|
||||
bitmask S3C2410_NFCONF_TWRPH0 = {4, 0x7};
|
||||
bitmask S3C2410_NFCONF_TWRPH1 = {0, 0x7};
|
||||
|
||||
bitmask S3C2410_NFSTAT_BUSY = {0, 0x1};
|
||||
|
||||
/* S3C2440 bits */
|
||||
bitmask S3C2440_2412_NFCONF_BUSWIDTH = {0, 0x1};
|
||||
#define S3C2440_NFCONF_BUSWIDTH_8 0
|
||||
#define S3C2440_NFCONF_BUSWIDTH_16 1
|
||||
|
||||
bitmask S3C2440_2412_NFCONF_TACLS = {12, 0x3};
|
||||
bitmask S3C2440_2412_NFCONF_TWRPH0 = {8, 0x7};
|
||||
bitmask S3C2440_2412_NFCONF_TWRPH1 = {4, 0x7};
|
||||
|
||||
bitmask S3C2440_NFCONT_LOCKTIGHT = {13, 0x1};
|
||||
bitmask S3C2440_NFCONT_SOFTLOCK = {12, 0x1};
|
||||
bitmask S3C2440_NFCONT_ILLEGALACC_EN = {10, 0x1};
|
||||
bitmask S3C2440_NFCONT_RNBINT_EN = {9, 0x1};
|
||||
bitmask S3C2440_NFCONT_RN_FALLING = {8, 0x1};
|
||||
bitmask S3C2440_NFCONT_SPARE_ECCLOCK = {6, 0x1};
|
||||
bitmask S3C2440_NFCONT_MAIN_ECCLOCK = {5, 0x1};
|
||||
bitmask S3C2440_NFCONT_INITECC = {4, 0x1};
|
||||
bitmask S3C2440_NFCONT_NFCE = {1, 0x1};
|
||||
bitmask S3C2440_2412_NFCONT_ENABLE = {0, 0x1};
|
||||
|
||||
bitmask S3C2440_NFSTAT_READY = {0, 0x1};
|
||||
bitmask S3C2440_NFSTAT_NCE = {1, 0x1};
|
||||
bitmask S3C2440_NFSTAT_RNB_CHANGE = {2, 0x1};
|
||||
bitmask S3C2440_NFSTAT_ILLEGAL_ACCESS = {3, 0x1};
|
||||
|
||||
/* S3C2412 bits */
|
||||
bitmask S3C2412_NFCONF_NANDBOOT = {31, 0x1};
|
||||
bitmask S3C2412_NFCONF_ECCCLKCON = {30, 0x1};
|
||||
bitmask S3C2412_NFCONF_ECC_MLC = {24, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_DIRWR = {18, 0x1};
|
||||
bitmask S3C2412_NFCONT_LOCKTIGHT = {17, 0x1};
|
||||
bitmask S3C2412_NFCONT_SOFTLOCK = {16, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_ENCINT = {13, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_DECINT = {12, 0x1};
|
||||
bitmask S3C2412_NFCONT_MAIN_ECC_LOCK = {7, 0x1};
|
||||
bitmask S3C2412_NFCONT_MAIN_SECONDARY_ECC_LOCK = {6, 0x1};
|
||||
bitmask S3C2412_NFCONT_INIT_MAIN_ECC = {5, 0x1};
|
||||
bitmask S3C2412_NFCONT_INIT_SECONDARY_ECC = {4, 0x1};
|
||||
bitmask S3C2412_NFCONT_nFCE1 = {2, 0x1};
|
||||
bitmask S3C2412_NFCONT_nFCE0 = {1, 0x1};
|
||||
|
||||
bitmask S3C2412_NFSTAT_ECC_ENCDONE = {7, 0x1};
|
||||
bitmask S3C2412_NFSTAT_ECC_DECDONE = {6, 0x1};
|
||||
bitmask S3C2412_NFSTAT_ILLEGAL_ACCESS = {5, 0x1};
|
||||
bitmask S3C2412_NFSTAT_RnB_CHANGE = {4, 0x1};
|
||||
bitmask S3C2412_NFSTAT_nFCE1 = {3, 0x1};
|
||||
bitmask S3C2412_NFSTAT_nFCE0 = {2, 0x1};
|
||||
bitmask S3C2412_NFSTAT_Res1 = {1, 0x1};
|
||||
bitmask S3C2412_NFSTAT_READY = {0, 0x1};
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define SYSTYPE_S3C2410 0
|
||||
#define SYSTYPE_S3C2440 1
|
||||
#define SYSTYPE_S3C2412 2
|
||||
|
||||
/* Common */
|
||||
#define S3C2410_2440_2412_NFCONF 0x00
|
||||
|
||||
/* S3C2410 */
|
||||
#define S3C2410_NFCMD 0x04
|
||||
#define S3C2410_NFADDR 0x08
|
||||
#define S3C2410_NFDATA 0x0C
|
||||
#define S3C2410_NFSTAT 0x10
|
||||
#define S3C2410_NFECC 0x14
|
||||
|
||||
/* S3C2440 */
|
||||
#define S3C2440_2412_NFCONT 0x04
|
||||
#define S3C2440_2412_NFCMD 0x08
|
||||
#define S3C2440_2412_NFADDR 0x0C
|
||||
#define S3C2440_2412_NFDATA 0x10
|
||||
#define S3C2440_2412_NFECCD0 0x14
|
||||
#define S3C2440_2412_NFECCD1 0x18
|
||||
#define S3C2440_2412_NFECCD 0x1C
|
||||
#define S3C2440_NFSTAT 0x20
|
||||
#define S3C2440_NFESTAT0 0x24
|
||||
#define S3C2440_NFESTAT1 0x28
|
||||
#define S3C2440_NFMECC0 0x2C
|
||||
#define S3C2440_NFMECC1 0x30
|
||||
#define S3C2440_NFSECC 0x34
|
||||
#define S3C2440_NFSBLK 0x38
|
||||
#define S3C2440_NFEBLK 0x3C
|
||||
|
||||
/* S3C2412 */
|
||||
#define S3C2412_NFSBLK 0x20
|
||||
#define S3C2412_NFEBLK 0x24
|
||||
#define S3C2412_NFSTAT 0x28
|
||||
#define S3C2412_NFMECC_ERR0 0x2C
|
||||
#define S3C2412_NFMECC_ERR1 0x30
|
||||
#define S3C2412_NFMECC0 0x34
|
||||
#define S3C2412_NFMECC1 0x38
|
||||
#define S3C2412_NFSECC 0x3C
|
||||
|
||||
/* S3C2410 bits */
|
||||
bitmask S3C2410_NFCONF_EN = {15, 0x1};
|
||||
bitmask S3C2410_NFCONF_INITECC = {12, 0x1};
|
||||
bitmask S3C2410_NFCONF_NFCE = {11, 0x1};
|
||||
bitmask S3C2410_NFCONF_TACLS = {8, 0x7};
|
||||
bitmask S3C2410_NFCONF_TWRPH0 = {4, 0x7};
|
||||
bitmask S3C2410_NFCONF_TWRPH1 = {0, 0x7};
|
||||
|
||||
bitmask S3C2410_NFSTAT_BUSY = {0, 0x1};
|
||||
|
||||
/* S3C2440 bits */
|
||||
bitmask S3C2440_2412_NFCONF_BUSWIDTH = {0, 0x1};
|
||||
#define S3C2440_NFCONF_BUSWIDTH_8 0
|
||||
#define S3C2440_NFCONF_BUSWIDTH_16 1
|
||||
|
||||
bitmask S3C2440_2412_NFCONF_TACLS = {12, 0x3};
|
||||
bitmask S3C2440_2412_NFCONF_TWRPH0 = {8, 0x7};
|
||||
bitmask S3C2440_2412_NFCONF_TWRPH1 = {4, 0x7};
|
||||
|
||||
bitmask S3C2440_NFCONT_LOCKTIGHT = {13, 0x1};
|
||||
bitmask S3C2440_NFCONT_SOFTLOCK = {12, 0x1};
|
||||
bitmask S3C2440_NFCONT_ILLEGALACC_EN = {10, 0x1};
|
||||
bitmask S3C2440_NFCONT_RNBINT_EN = {9, 0x1};
|
||||
bitmask S3C2440_NFCONT_RN_FALLING = {8, 0x1};
|
||||
bitmask S3C2440_NFCONT_SPARE_ECCLOCK = {6, 0x1};
|
||||
bitmask S3C2440_NFCONT_MAIN_ECCLOCK = {5, 0x1};
|
||||
bitmask S3C2440_NFCONT_INITECC = {4, 0x1};
|
||||
bitmask S3C2440_NFCONT_NFCE = {1, 0x1};
|
||||
bitmask S3C2440_2412_NFCONT_ENABLE = {0, 0x1};
|
||||
|
||||
bitmask S3C2440_NFSTAT_READY = {0, 0x1};
|
||||
bitmask S3C2440_NFSTAT_NCE = {1, 0x1};
|
||||
bitmask S3C2440_NFSTAT_RNB_CHANGE = {2, 0x1};
|
||||
bitmask S3C2440_NFSTAT_ILLEGAL_ACCESS = {3, 0x1};
|
||||
|
||||
/* S3C2412 bits */
|
||||
bitmask S3C2412_NFCONF_NANDBOOT = {31, 0x1};
|
||||
bitmask S3C2412_NFCONF_ECCCLKCON = {30, 0x1};
|
||||
bitmask S3C2412_NFCONF_ECC_MLC = {24, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_DIRWR = {18, 0x1};
|
||||
bitmask S3C2412_NFCONT_LOCKTIGHT = {17, 0x1};
|
||||
bitmask S3C2412_NFCONT_SOFTLOCK = {16, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_ENCINT = {13, 0x1};
|
||||
bitmask S3C2412_NFCONT_ECC4_DECINT = {12, 0x1};
|
||||
bitmask S3C2412_NFCONT_MAIN_ECC_LOCK = {7, 0x1};
|
||||
bitmask S3C2412_NFCONT_MAIN_SECONDARY_ECC_LOCK = {6, 0x1};
|
||||
bitmask S3C2412_NFCONT_INIT_MAIN_ECC = {5, 0x1};
|
||||
bitmask S3C2412_NFCONT_INIT_SECONDARY_ECC = {4, 0x1};
|
||||
bitmask S3C2412_NFCONT_nFCE1 = {2, 0x1};
|
||||
bitmask S3C2412_NFCONT_nFCE0 = {1, 0x1};
|
||||
|
||||
bitmask S3C2412_NFSTAT_ECC_ENCDONE = {7, 0x1};
|
||||
bitmask S3C2412_NFSTAT_ECC_DECDONE = {6, 0x1};
|
||||
bitmask S3C2412_NFSTAT_ILLEGAL_ACCESS = {5, 0x1};
|
||||
bitmask S3C2412_NFSTAT_RnB_CHANGE = {4, 0x1};
|
||||
bitmask S3C2412_NFSTAT_nFCE1 = {3, 0x1};
|
||||
bitmask S3C2412_NFSTAT_nFCE0 = {2, 0x1};
|
||||
bitmask S3C2412_NFSTAT_Res1 = {1, 0x1};
|
||||
bitmask S3C2412_NFSTAT_READY = {0, 0x1};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Samsung S3C2440 NAND Controller */
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2440
|
||||
|
||||
/* Samsung S3C2440 NAND Controller */
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2440
|
||||
|
||||
#include "s3c2410.c"
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* Samsung S3C6410 NAND Controller */
|
||||
#define NAND_BASE 0x70200000
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2412
|
||||
|
||||
/* Samsung S3C6410 NAND Controller */
|
||||
#define NAND_BASE 0x70200000
|
||||
#define NAND_SYS_TYPE SYSTYPE_S3C2412
|
||||
|
||||
#include "s3c2410.c"
|
||||
|
|
@ -1,32 +1,32 @@
|
|||
#include "nand.h"
|
||||
#include "controller/controller.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN NAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
return NAND_Ctrl_Probe(mem);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
uint32_t spare_offset = size;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = NAND_Ctrl_Read(mem, dest + page_offset, dest + spare_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
spare_offset += mem->page_size >> 5;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = spare_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver nand_controller = {
|
||||
.initialize = NAND_Probe,
|
||||
.read = NAND_Read
|
||||
#include "nand.h"
|
||||
#include "controller/controller.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN NAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
return NAND_Ctrl_Probe(mem);
|
||||
}
|
||||
|
||||
DCC_RETURN NAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
uint32_t spare_offset = size;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = NAND_Ctrl_Read(mem, dest + page_offset, dest + spare_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
spare_offset += mem->page_size >> 5;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = spare_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver nand_controller = {
|
||||
.initialize = NAND_Probe,
|
||||
.read = NAND_Read
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
extern Driver nand_controller;
|
||||
|
|
@ -1,65 +1,65 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define O1N_BOOTRAM 0x0000
|
||||
#define O1N_DATARAM 0x0200
|
||||
#define O1N_SPARERAM 0x8010
|
||||
#define O1N_REG_MANUFACTURER_ID 0xF000
|
||||
#define O1N_REG_DEVICE_ID 0xF001
|
||||
#define O1N_REG_VERSION_ID 0xF002
|
||||
#define O1N_REG_DATA_BUFFER_SIZE 0xF003
|
||||
#define O1N_REG_BOOT_BUFFER_SIZE 0xF004
|
||||
#define O1N_REG_NUM_BUFFERS 0xF005
|
||||
#define O1N_REG_TECHNOLOGY 0xF006
|
||||
#define O1N_REG_START_ADDRESS1 0xF100
|
||||
#define O1N_REG_START_ADDRESS2 0xF101
|
||||
#define O1N_REG_START_ADDRESS3 0xF102
|
||||
#define O1N_REG_START_ADDRESS4 0xF103
|
||||
#define O1N_REG_START_ADDRESS5 0xF104
|
||||
#define O1N_REG_START_ADDRESS6 0xF105
|
||||
#define O1N_REG_START_ADDRESS7 0xF106
|
||||
#define O1N_REG_START_ADDRESS8 0xF107
|
||||
#define O1N_REG_START_BUFFER 0xF200
|
||||
#define O1N_REG_COMMAND 0xF220
|
||||
#define O1N_REG_SYS_CFG1 0xF221
|
||||
#define O1N_REG_SYS_CFG2 0xF222
|
||||
#define O1N_REG_CTRL_STATUS 0xF240
|
||||
#define O1N_REG_INTERRUPT 0xF241
|
||||
#define O1N_REG_START_BLOCK_ADDRESS 0xF24C
|
||||
#define O1N_REG_END_BLOCK_ADDRESS 0xF24D
|
||||
#define O1N_REG_WP_STATUS 0xF24E
|
||||
#define O1N_REG_ECC_STATUS 0xFF00
|
||||
#define O1N_REG_ECC_M0 0xFF01
|
||||
#define O1N_REG_ECC_S0 0xFF02
|
||||
#define O1N_REG_ECC_M1 0xFF03
|
||||
#define O1N_REG_ECC_S1 0xFF04
|
||||
#define O1N_REG_ECC_M2 0xFF05
|
||||
#define O1N_REG_ECC_S2 0xFF06
|
||||
#define O1N_REG_ECC_M3 0xFF07
|
||||
#define O1N_REG_ECC_S3 0xFF08
|
||||
|
||||
#define O1N_CMD_READ 0x00
|
||||
#define O1N_CMD_READOOB 0x13
|
||||
#define O1N_CMD_PROG 0x80
|
||||
#define O1N_CMD_PROGOOB 0x1A
|
||||
#define O1N_CMD_X2_PROG 0x7D
|
||||
#define O1N_CMD_X2_CACHE_PROG 0x7F
|
||||
#define O1N_CMD_UNLOCK 0x23
|
||||
#define O1N_CMD_LOCK 0x2A
|
||||
#define O1N_CMD_LOCK_TIGHT 0x2C
|
||||
#define O1N_CMD_UNLOCK_ALL 0x27
|
||||
#define O1N_CMD_ERASE 0x94
|
||||
#define O1N_CMD_MULTIBLOCK_ERASE 0x95
|
||||
#define O1N_CMD_ERASE_VERIFY 0x71
|
||||
#define O1N_CMD_RESET 0xF0
|
||||
#define O1N_CMD_HOT_RESET 0xF3
|
||||
#define O1N_CMD_OTP_ACCESS 0x65
|
||||
#define O1N_CMD_READID 0x90
|
||||
#define O1N_CMD_PI_UPDATE 0x05
|
||||
#define O1N_CMD_PI_ACCESS 0x66
|
||||
#define O1N_CMD_RECOVER_LSB 0x05
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset);
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data);
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg);
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size);
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define O1N_BOOTRAM 0x0000
|
||||
#define O1N_DATARAM 0x0200
|
||||
#define O1N_SPARERAM 0x8010
|
||||
#define O1N_REG_MANUFACTURER_ID 0xF000
|
||||
#define O1N_REG_DEVICE_ID 0xF001
|
||||
#define O1N_REG_VERSION_ID 0xF002
|
||||
#define O1N_REG_DATA_BUFFER_SIZE 0xF003
|
||||
#define O1N_REG_BOOT_BUFFER_SIZE 0xF004
|
||||
#define O1N_REG_NUM_BUFFERS 0xF005
|
||||
#define O1N_REG_TECHNOLOGY 0xF006
|
||||
#define O1N_REG_START_ADDRESS1 0xF100
|
||||
#define O1N_REG_START_ADDRESS2 0xF101
|
||||
#define O1N_REG_START_ADDRESS3 0xF102
|
||||
#define O1N_REG_START_ADDRESS4 0xF103
|
||||
#define O1N_REG_START_ADDRESS5 0xF104
|
||||
#define O1N_REG_START_ADDRESS6 0xF105
|
||||
#define O1N_REG_START_ADDRESS7 0xF106
|
||||
#define O1N_REG_START_ADDRESS8 0xF107
|
||||
#define O1N_REG_START_BUFFER 0xF200
|
||||
#define O1N_REG_COMMAND 0xF220
|
||||
#define O1N_REG_SYS_CFG1 0xF221
|
||||
#define O1N_REG_SYS_CFG2 0xF222
|
||||
#define O1N_REG_CTRL_STATUS 0xF240
|
||||
#define O1N_REG_INTERRUPT 0xF241
|
||||
#define O1N_REG_START_BLOCK_ADDRESS 0xF24C
|
||||
#define O1N_REG_END_BLOCK_ADDRESS 0xF24D
|
||||
#define O1N_REG_WP_STATUS 0xF24E
|
||||
#define O1N_REG_ECC_STATUS 0xFF00
|
||||
#define O1N_REG_ECC_M0 0xFF01
|
||||
#define O1N_REG_ECC_S0 0xFF02
|
||||
#define O1N_REG_ECC_M1 0xFF03
|
||||
#define O1N_REG_ECC_S1 0xFF04
|
||||
#define O1N_REG_ECC_M2 0xFF05
|
||||
#define O1N_REG_ECC_S2 0xFF06
|
||||
#define O1N_REG_ECC_M3 0xFF07
|
||||
#define O1N_REG_ECC_S3 0xFF08
|
||||
|
||||
#define O1N_CMD_READ 0x00
|
||||
#define O1N_CMD_READOOB 0x13
|
||||
#define O1N_CMD_PROG 0x80
|
||||
#define O1N_CMD_PROGOOB 0x1A
|
||||
#define O1N_CMD_X2_PROG 0x7D
|
||||
#define O1N_CMD_X2_CACHE_PROG 0x7F
|
||||
#define O1N_CMD_UNLOCK 0x23
|
||||
#define O1N_CMD_LOCK 0x2A
|
||||
#define O1N_CMD_LOCK_TIGHT 0x2C
|
||||
#define O1N_CMD_UNLOCK_ALL 0x27
|
||||
#define O1N_CMD_ERASE 0x94
|
||||
#define O1N_CMD_MULTIBLOCK_ERASE 0x95
|
||||
#define O1N_CMD_ERASE_VERIFY 0x71
|
||||
#define O1N_CMD_RESET 0xF0
|
||||
#define O1N_CMD_HOT_RESET 0xF3
|
||||
#define O1N_CMD_OTP_ACCESS 0x65
|
||||
#define O1N_CMD_READID 0x90
|
||||
#define O1N_CMD_PI_UPDATE 0x05
|
||||
#define O1N_CMD_PI_ACCESS 0x66
|
||||
#define O1N_CMD_RECOVER_LSB 0x05
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset);
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data);
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg);
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size);
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
/* OneNAND controller template */
|
||||
|
||||
#include "../onenand.h"
|
||||
#include "controller.h"
|
||||
#include <stdint.h>
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
|
||||
// Initialize routines
|
||||
mem->base_offset = offset;
|
||||
mem->page_size = 0x800;
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data) {
|
||||
// Write register routines
|
||||
WRITE_U16(mem->base_offset + (reg << 1), data);
|
||||
}
|
||||
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg) {
|
||||
// Read register routines
|
||||
return READ_U16(mem->base_offset + (reg << 1));
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size) {
|
||||
PLAT_MEMCPY(page_buf, (uint8_t *)(mem->base_offset + (O1N_DATARAM << 1)), page_size);
|
||||
PLAT_MEMCPY(spare_buf, (uint8_t *)(mem->base_offset + (O1N_SPARERAM << 1)), spare_size);
|
||||
}
|
||||
|
||||
/* OneNAND controller template */
|
||||
|
||||
#include "../onenand.h"
|
||||
#include "controller.h"
|
||||
#include <stdint.h>
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
|
||||
// Initialize routines
|
||||
mem->base_offset = offset;
|
||||
mem->page_size = 0x800;
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data) {
|
||||
// Write register routines
|
||||
WRITE_U16(mem->base_offset + (reg << 1), data);
|
||||
}
|
||||
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg) {
|
||||
// Read register routines
|
||||
return READ_U16(mem->base_offset + (reg << 1));
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size) {
|
||||
PLAT_MEMCPY(page_buf, (uint8_t *)(mem->base_offset + (O1N_DATARAM << 1)), page_size);
|
||||
PLAT_MEMCPY(spare_buf, (uint8_t *)(mem->base_offset + (O1N_SPARERAM << 1)), spare_size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,97 +1,97 @@
|
|||
// Qualcomm MSM7xxx OneNAND through SFLASH Interface
|
||||
|
||||
#include "../onenand.h"
|
||||
#include "msm7200.h"
|
||||
#include "../controller.h"
|
||||
#include <stdint.h>
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0xa0a00000
|
||||
#endif
|
||||
|
||||
#define MSM_NAND_SFTRNSTYPE_DATXS 0x0
|
||||
#define MSM_NAND_SFTRNSTYPE_CMDXS 0x1
|
||||
|
||||
#define MSM_NAND_SFMODE_BURST 0x0
|
||||
#define MSM_NAND_SFMODE_ASYNC 0x1
|
||||
|
||||
#define MSM_NAND_SFCMD_ABORT 0x1
|
||||
#define MSM_NAND_SFCMD_REGRD 0x2
|
||||
#define MSM_NAND_SFCMD_REGWR 0x3
|
||||
#define MSM_NAND_SFCMD_INTLO 0x4
|
||||
#define MSM_NAND_SFCMD_INTHI 0x5
|
||||
#define MSM_NAND_SFCMD_DATRD 0x6
|
||||
#define MSM_NAND_SFCMD_DATWR 0x7
|
||||
|
||||
// ASYNC_READ_MASK = Mode = ASYNC, TRNSTYPE = DATA
|
||||
// ASYNC_WRITE_MASK = Mode = ASYNC, TRNSTYPE = CMD
|
||||
|
||||
#define SFLASH_CMD(num_words, offset_val, delta_val, transfer_type, mode, opcode) \
|
||||
((num_words << 20) | (offset_val << 12) | (delta_val << 6) | (transfer_type << 5) | (mode << 4) | opcode)
|
||||
|
||||
void inline SFLASHC_Execute(void) {
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, MSM7200_SFLASHC_EXEC_CMD_BUSY));
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, MSM7200_SFLASHC_EXEC_CMD_BUSY));
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_STATUS, MSM7200_SFLASHC_OPER_STATUS));
|
||||
}
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
|
||||
// Initialize routines
|
||||
mem->base_offset = offset;
|
||||
mem->page_size = 0x800;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, 0xaad4001a);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, 0x2101bd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD_VLD, 0xd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_BURST_CFG, 0x20100327);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP1, 0x47804780);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP2, 0x39003a0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP3, 0x3b008a8);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP4, 0x9b488a0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP5, 0x89a2c420);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP6, 0xc420c020);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP7, 0xc020c020);
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data) {
|
||||
// Write register routines
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, reg);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_GENP_REG0, data);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(1, 0, 0, MSM_NAND_SFTRNSTYPE_CMDXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_REGWR));
|
||||
SFLASHC_Execute();
|
||||
}
|
||||
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg) {
|
||||
// Read register routines
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, reg);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(1, 0, 0, MSM_NAND_SFTRNSTYPE_DATXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_REGRD));
|
||||
SFLASHC_Execute();
|
||||
|
||||
return (uint16_t)READ_U32(REGS_START + MSM7200_REG_GENP_REG0);
|
||||
}
|
||||
|
||||
void SFLASHC_Nand2Buf(uint16_t offset, uint8_t *data, uint16_t size) {
|
||||
uint16_t buf_offset = 0;
|
||||
|
||||
while (size > 0) {
|
||||
uint32_t read_size = size > 512 ? 512 : size;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_MACRO1_REG, offset);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(read_size >> 1, 0, 0, MSM_NAND_SFTRNSTYPE_DATXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_DATRD));
|
||||
|
||||
SFLASHC_Execute();
|
||||
PLAT_MEMCPY(data + buf_offset, (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER), read_size);
|
||||
|
||||
size -= read_size;
|
||||
buf_offset += read_size;
|
||||
offset += read_size >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size) {
|
||||
SFLASHC_Nand2Buf(O1N_DATARAM, page_buf, page_size);
|
||||
SFLASHC_Nand2Buf(O1N_SPARERAM, spare_buf, spare_size);
|
||||
}
|
||||
|
||||
// Qualcomm MSM7xxx OneNAND through SFLASH Interface
|
||||
|
||||
#include "../onenand.h"
|
||||
#include "msm7200.h"
|
||||
#include "../controller.h"
|
||||
#include <stdint.h>
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#ifndef REGS_START
|
||||
#define REGS_START 0xa0a00000
|
||||
#endif
|
||||
|
||||
#define MSM_NAND_SFTRNSTYPE_DATXS 0x0
|
||||
#define MSM_NAND_SFTRNSTYPE_CMDXS 0x1
|
||||
|
||||
#define MSM_NAND_SFMODE_BURST 0x0
|
||||
#define MSM_NAND_SFMODE_ASYNC 0x1
|
||||
|
||||
#define MSM_NAND_SFCMD_ABORT 0x1
|
||||
#define MSM_NAND_SFCMD_REGRD 0x2
|
||||
#define MSM_NAND_SFCMD_REGWR 0x3
|
||||
#define MSM_NAND_SFCMD_INTLO 0x4
|
||||
#define MSM_NAND_SFCMD_INTHI 0x5
|
||||
#define MSM_NAND_SFCMD_DATRD 0x6
|
||||
#define MSM_NAND_SFCMD_DATWR 0x7
|
||||
|
||||
// ASYNC_READ_MASK = Mode = ASYNC, TRNSTYPE = DATA
|
||||
// ASYNC_WRITE_MASK = Mode = ASYNC, TRNSTYPE = CMD
|
||||
|
||||
#define SFLASH_CMD(num_words, offset_val, delta_val, transfer_type, mode, opcode) \
|
||||
((num_words << 20) | (offset_val << 12) | (delta_val << 6) | (transfer_type << 5) | (mode << 4) | opcode)
|
||||
|
||||
void inline SFLASHC_Execute(void) {
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, MSM7200_SFLASHC_EXEC_CMD_BUSY));
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, 1);
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_EXEC_CMD, MSM7200_SFLASHC_EXEC_CMD_BUSY));
|
||||
do { wdog_reset(); } while (GET_BIT32(REGS_START + MSM7200_REG_SFLASHC_STATUS, MSM7200_SFLASHC_OPER_STATUS));
|
||||
}
|
||||
|
||||
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
|
||||
// Initialize routines
|
||||
mem->base_offset = offset;
|
||||
mem->page_size = 0x800;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, 0xaad4001a);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, 0x2101bd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_DEV_CMD_VLD, 0xd);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_BURST_CFG, 0x20100327);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP1, 0x47804780);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP2, 0x39003a0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP3, 0x3b008a8);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP4, 0x9b488a0);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP5, 0x89a2c420);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP6, 0xc420c020);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_XFR_STEP7, 0xc020c020);
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data) {
|
||||
// Write register routines
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, reg);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_GENP_REG0, data);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(1, 0, 0, MSM_NAND_SFTRNSTYPE_CMDXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_REGWR));
|
||||
SFLASHC_Execute();
|
||||
}
|
||||
|
||||
uint16_t OneNAND_Ctrl_Reg_Read(DCCMemory *mem, uint16_t reg) {
|
||||
// Read register routines
|
||||
WRITE_U32(REGS_START + MSM7200_REG_ADDR0, reg);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(1, 0, 0, MSM_NAND_SFTRNSTYPE_DATXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_REGRD));
|
||||
SFLASHC_Execute();
|
||||
|
||||
return (uint16_t)READ_U32(REGS_START + MSM7200_REG_GENP_REG0);
|
||||
}
|
||||
|
||||
void SFLASHC_Nand2Buf(uint16_t offset, uint8_t *data, uint16_t size) {
|
||||
uint16_t buf_offset = 0;
|
||||
|
||||
while (size > 0) {
|
||||
uint32_t read_size = size > 512 ? 512 : size;
|
||||
|
||||
WRITE_U32(REGS_START + MSM7200_REG_MACRO1_REG, offset);
|
||||
WRITE_U32(REGS_START + MSM7200_REG_SFLASHC_CMD, SFLASH_CMD(read_size >> 1, 0, 0, MSM_NAND_SFTRNSTYPE_DATXS, MSM_NAND_SFMODE_BURST, MSM_NAND_SFCMD_DATRD));
|
||||
|
||||
SFLASHC_Execute();
|
||||
PLAT_MEMCPY(data + buf_offset, (uint8_t *)(REGS_START + MSM7200_REG_FLASH_BUFFER), read_size);
|
||||
|
||||
size -= read_size;
|
||||
buf_offset += read_size;
|
||||
offset += read_size >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
void OneNAND_Ctrl_Get_Data(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page_size, uint32_t spare_size) {
|
||||
SFLASHC_Nand2Buf(O1N_DATARAM, page_buf, page_size);
|
||||
SFLASHC_Nand2Buf(O1N_SPARERAM, spare_buf, spare_size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,346 +1,346 @@
|
|||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM7200_REG_FLASH_CMD 0x0000
|
||||
#define MSM7200_REG_ADDR0 0x0004
|
||||
#define MSM7200_REG_ADDR1 0x0008
|
||||
#define MSM7200_REG_FLASH_CHIP_SELECT 0x000C
|
||||
#define MSM7200_REG_EXEC_CMD 0x0010
|
||||
#define MSM7200_REG_FLASH_STATUS 0x0014
|
||||
#define MSM7200_REG_BUFFER_STATUS 0x0018
|
||||
#define MSM7200_REG_SFLASHC_STATUS 0x001C
|
||||
#define MSM7200_REG_DEV0_CFG0 0x0020
|
||||
#define MSM7200_REG_DEV0_CFG1 0x0024
|
||||
#define MSM7200_REG_DEV0_ECC_CFG 0x0028
|
||||
#define MSM7200_REG_DEV1_ECC_CFG 0x002C
|
||||
#define MSM7200_REG_DEV1_CFG0 0x0030
|
||||
#define MSM7200_REG_DEV1_CFG1 0x0034
|
||||
#define MSM7200_REG_SFLASHC_CMD 0x0038
|
||||
#define MSM7200_REG_SFLASHC_EXEC_CMD 0x003C
|
||||
#define MSM7200_REG_READ_ID 0x0040
|
||||
#define MSM7200_REG_READ_STATUS 0x0044
|
||||
#define MSM7200_REG_CONFIG_DATA 0x0050
|
||||
#define MSM7200_REG_CONFIG 0x0054
|
||||
#define MSM7200_REG_CONFIG_MODE 0x0058
|
||||
#define MSM7200_REG_CONFIG_STATUS 0x0060
|
||||
#define MSM7200_REG_MACRO1_REG 0x0064
|
||||
#define MSM7200_REG_XFR_STEP1 0x0070
|
||||
#define MSM7200_REG_XFR_STEP2 0x0074
|
||||
#define MSM7200_REG_XFR_STEP3 0x0078
|
||||
#define MSM7200_REG_XFR_STEP4 0x007C
|
||||
#define MSM7200_REG_XFR_STEP5 0x0080
|
||||
#define MSM7200_REG_XFR_STEP6 0x0084
|
||||
#define MSM7200_REG_XFR_STEP7 0x0088
|
||||
#define MSM7200_REG_GENP_REG0 0x0090
|
||||
#define MSM7200_REG_GENP_REG1 0x0094
|
||||
#define MSM7200_REG_GENP_REG2 0x0098
|
||||
#define MSM7200_REG_GENP_REG3 0x009C
|
||||
#define MSM7200_REG_DEV_CMD0 0x00A0
|
||||
#define MSM7200_REG_DEV_CMD1 0x00A4
|
||||
#define MSM7200_REG_DEV_CMD2 0x00A8
|
||||
#define MSM7200_REG_DEV_CMD_VLD 0x00AC
|
||||
#define MSM7200_REG_EBI2_MISR_SIG_REG 0x00B0
|
||||
#define MSM7200_REG_ADDR2 0x00C0
|
||||
#define MSM7200_REG_ADDR3 0x00C4
|
||||
#define MSM7200_REG_ADDR4 0x00C8
|
||||
#define MSM7200_REG_ADDR5 0x00CC
|
||||
#define MSM7200_REG_DEV_CMD3 0x00D0
|
||||
#define MSM7200_REG_DEV_CMD4 0x00D4
|
||||
#define MSM7200_REG_DEV_CMD5 0x00D8
|
||||
#define MSM7200_REG_DEV_CMD6 0x00DC
|
||||
#define MSM7200_REG_SFLASHC_BURST_CFG 0x00E0
|
||||
#define MSM7200_REG_ADDR6 0x00E4
|
||||
#define MSM7200_REG_EBI2_ECC_BUF_CFG 0x00F0
|
||||
#define MSM7200_REG_HW_INFO 0x00FC
|
||||
#define MSM7200_REG_FLASH_BUFFER 0x0100
|
||||
#define MSM7200_REG_NAND_MPU_ENABLE 0x100000
|
||||
|
||||
#define MSM7200_CMD_RESET 0x31
|
||||
#define MSM7200_CMD_PAGE_READ 0x32
|
||||
#define MSM7200_CMD_PAGE_READ_ECC 0x33
|
||||
#define MSM7200_CMD_PAGE_READ_ALL 0x34
|
||||
#define MSM7200_CMD_SEQ_PAGE_READ 0x15
|
||||
#define MSM7200_CMD_PRG_PAGE 0x36
|
||||
#define MSM7200_CMD_PRG_PAGE_ECC 0x37
|
||||
#define MSM7200_CMD_PRG_PAGE_ALL 0x39
|
||||
#define MSM7200_CMD_BLOCK_ERASE 0x3A
|
||||
#define MSM7200_CMD_FETCH_ID 0x0B
|
||||
#define MSM7200_CMD_STATUS 0x0C
|
||||
#define MSM7200_CMD_RESET_NAND 0x0D
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_LAST = {26, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_SEQ = {25, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_READ_CACHE_NEXT_CMD = {24, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_PROGRAM_PAGE_CACHE_NEXT_CMD = {20, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EXTENDED_FETCH_ID = {19, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_INTR_STATUS = {18, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_HOST_CFG = {17, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE = {7, 0x3ff};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_LAST_PAGE = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_PAGE_ACC = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_OP_CMD = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_NON_PAGE_ACCESS_COMMAND 0
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_PAGE_ACCESS_COMMAND 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_0 0
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC_SPARE 4
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_PROGRAM_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_8 8
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESET_NAND_FLASH_DEVICE_OR_ONENAND_REGISTER_WRITE 13
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_E 14
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_F 15
|
||||
|
||||
bitmask MSM7200_NAND_ADDR0_DEV_ADDR0 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR1_DEV_ADDR1 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_RESET_XFR_STEP_LOAD_DONE_STATUS = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_ONE_NAND_EN = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_DM_EN = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN_DYNAMICALLY_CHANGING_THE_XFR_STEP2_IS_ENABLED 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_DISABLE 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_ENABLE 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS0_IS_SELECTED 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS1_IS_SELECTED 1
|
||||
|
||||
bitmask MSM7200_NANDC_EXEC_CMD_EXEC_CMD = {0, 0x1};
|
||||
#define MSM7200_NANDC_EXEC_CMD_EXEC_CMD_EXECUTE_THE_COMMAND 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_DEV_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_CODEWORD_CNTR = {12, 0xf};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE = {11, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE = {10, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_MPU_ERROR = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_PROG_ERASE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_READY_BSY_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OP_ERR = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OPER_STATUS = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_NOT_A_2K_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_ENUM_2K_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_NOT_A_512_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_ENUM_512_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_MPU_ERROR_FOR_THE_ACCESS 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_ERROR 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_BUSY 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_READY 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_IDLE_STATE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC_AND_SPARE_DATA 4
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_SEQUENTIAL_PAGE_READ 5
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESERVED_PROGRAMMING 8
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESET_FLASH_DEVICE 13
|
||||
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_BAD_BLOCK_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_XFR_STEP2_REG_UPDATE_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_UNCORRECTABLE = {8, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_NUM_ERRORS = {0, 0x1f};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SET_RD_MODE_AFTER_STATUS = {31, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_STATUS_BFR_READ = {30, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES = {27, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SPARE_SIZE_BYTES = {23, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ECC_PARITY_SIZE_BYTES = {19, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_UD_SIZE_BYTES = {9, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_CW_PER_PAGE = {6, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES = {3, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES = {0, 0x7};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES_NO_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__1_CODEWORD_PER_PAGE 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__2_CODEWORDS_PER_PAGE 1
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__3_CODEWORDS_PER_PAGE 2
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__4_CODEWORDS_PER_PAGE 3
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__5_CODEWORDS_PER_PAGE 4
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__6_CODEWORDS_PER_PAGE 5
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__7_CODEWORDS_PER_PAGE 6
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__8_CODEWORDS_PER_PAGE 7
|
||||
#define MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES_NO_ROW_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES_NO_COLUMN_ADDRESS_CYCLES 0
|
||||
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_MODE = {28, 0x3};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ENABLE_BCH_ECC = {27, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_DISABLE_ECC_RESET_AFTER_OPDONE = {25, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DECODER_CGC_EN = {24, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_ENCODER_CGC_EN = {23, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP = {17, 0x3f};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA = {16, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM = {6, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY = {5, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES = {2, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WIDE_FLASH = {1, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DISABLE = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_2_CLOCK_CYCLE_GAP 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_4_CLOCK_CYCLES_GAP 1
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_6_CLOCK_CYCLES_GAP 2
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_8_CLOCK_CYCLES_GAP 3
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_10_CLOCK_CYCLES_GAP 4
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_128_CLOCK_CYCLES_GAP 63
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_USER_DATA_AREA 0
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_SPARE_AREA 1
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ALLOW_CS_DE_ASSERTION 0
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ASSERT_CS_DURING_BUSY 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_1_RECOVERY_CYCLE 0
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_2_RECOVERY_CYCLES 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_3_RECOVERY_CYCLES 2
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_8_RECOVERY_CYCLES 7
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_8_BIT_DATA_BUS 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_16_BIT_DATA_BUS 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_READ_ID_READ_ID = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_ECC_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_DEV_STATUS = {0, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_DATA_IN = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ADDR_OUT = {14, 0x3};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT_EN = {13, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN = {10, 0x7};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS5_N = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS4_N = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS3_N = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS2_N = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS1_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS0_N = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ALE = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CLE = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_WE_N = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_RE_N = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_DONT_READ 0
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_15_0 1
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_31_16 2
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_READ_STATUS_15_0 3
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_MODE_CONFIG_ACC = {0, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_STATUS_CONFIG_MODE = {0, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_ADDR_BUS_HOLD_CYCLE = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_DATA_START_ADDR = {0, 0xffff};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO1 = {14, 0x3f};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO0 = {0, 0x3fff};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER = {30, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_STEP1_WAIT = {26, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN = {25, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_DATA_EN = {24, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CE_EN = {23, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CLE_EN = {22, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN = {21, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WE_EN = {20, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_RE_EN = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WIDE = {18, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER = {14, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_STEP1_WAIT = {10, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN = {9, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_DATA_EN = {8, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CE_EN = {7, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CLE_EN = {6, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN = {5, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WE_EN = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_RE_EN = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WIDE = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_EXTA_READ_WAIT = {0, 0x3};
|
||||
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_SIMPLE_STEP 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_8_BIT_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_16_BIT_BUS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE_8_BIT_DATA_BUS_FOR_DATA 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE16_BIT_DATA_BUS_FOR_DATA 1
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_START = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_ADDR = {16, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_START = {8, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_ADDR = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_PARAMETER_PAGE_CODE = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_SEQ_READ_START_VLD = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_ERASE_START_VLD = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_WRITE_START_VLD = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_STOP_VLD = {1, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_START_VLD = {0, 0x1};
|
||||
|
||||
bitmask MSM7200_EBI2_MISR_SIG_REG_EBI2_MISR_SIG = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR2_DEV_ADDR2 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR3_DEV_ADDR3 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR4_DEV_ADDR4 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR5_DEV_ADDR5 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_LAST = {24, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_SEQ = {16, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_WRITE_START_CACHE = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD4 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD3 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD6 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD5 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD8 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD7 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR6_DEV_ADDR6 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_EBI2_ECC_BUF_CFG_NUM_STEPS = {0, 0x3ff};
|
||||
|
||||
bitmask MSM7200_FLASH_BUFF0_ACC_BUFF_DATA = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_SFLASHC_EXEC_CMD_BUSY = {0, 0x1};
|
||||
#pragma once
|
||||
#include "dcc/bitutils.h"
|
||||
|
||||
#define MSM7200_REG_FLASH_CMD 0x0000
|
||||
#define MSM7200_REG_ADDR0 0x0004
|
||||
#define MSM7200_REG_ADDR1 0x0008
|
||||
#define MSM7200_REG_FLASH_CHIP_SELECT 0x000C
|
||||
#define MSM7200_REG_EXEC_CMD 0x0010
|
||||
#define MSM7200_REG_FLASH_STATUS 0x0014
|
||||
#define MSM7200_REG_BUFFER_STATUS 0x0018
|
||||
#define MSM7200_REG_SFLASHC_STATUS 0x001C
|
||||
#define MSM7200_REG_DEV0_CFG0 0x0020
|
||||
#define MSM7200_REG_DEV0_CFG1 0x0024
|
||||
#define MSM7200_REG_DEV0_ECC_CFG 0x0028
|
||||
#define MSM7200_REG_DEV1_ECC_CFG 0x002C
|
||||
#define MSM7200_REG_DEV1_CFG0 0x0030
|
||||
#define MSM7200_REG_DEV1_CFG1 0x0034
|
||||
#define MSM7200_REG_SFLASHC_CMD 0x0038
|
||||
#define MSM7200_REG_SFLASHC_EXEC_CMD 0x003C
|
||||
#define MSM7200_REG_READ_ID 0x0040
|
||||
#define MSM7200_REG_READ_STATUS 0x0044
|
||||
#define MSM7200_REG_CONFIG_DATA 0x0050
|
||||
#define MSM7200_REG_CONFIG 0x0054
|
||||
#define MSM7200_REG_CONFIG_MODE 0x0058
|
||||
#define MSM7200_REG_CONFIG_STATUS 0x0060
|
||||
#define MSM7200_REG_MACRO1_REG 0x0064
|
||||
#define MSM7200_REG_XFR_STEP1 0x0070
|
||||
#define MSM7200_REG_XFR_STEP2 0x0074
|
||||
#define MSM7200_REG_XFR_STEP3 0x0078
|
||||
#define MSM7200_REG_XFR_STEP4 0x007C
|
||||
#define MSM7200_REG_XFR_STEP5 0x0080
|
||||
#define MSM7200_REG_XFR_STEP6 0x0084
|
||||
#define MSM7200_REG_XFR_STEP7 0x0088
|
||||
#define MSM7200_REG_GENP_REG0 0x0090
|
||||
#define MSM7200_REG_GENP_REG1 0x0094
|
||||
#define MSM7200_REG_GENP_REG2 0x0098
|
||||
#define MSM7200_REG_GENP_REG3 0x009C
|
||||
#define MSM7200_REG_DEV_CMD0 0x00A0
|
||||
#define MSM7200_REG_DEV_CMD1 0x00A4
|
||||
#define MSM7200_REG_DEV_CMD2 0x00A8
|
||||
#define MSM7200_REG_DEV_CMD_VLD 0x00AC
|
||||
#define MSM7200_REG_EBI2_MISR_SIG_REG 0x00B0
|
||||
#define MSM7200_REG_ADDR2 0x00C0
|
||||
#define MSM7200_REG_ADDR3 0x00C4
|
||||
#define MSM7200_REG_ADDR4 0x00C8
|
||||
#define MSM7200_REG_ADDR5 0x00CC
|
||||
#define MSM7200_REG_DEV_CMD3 0x00D0
|
||||
#define MSM7200_REG_DEV_CMD4 0x00D4
|
||||
#define MSM7200_REG_DEV_CMD5 0x00D8
|
||||
#define MSM7200_REG_DEV_CMD6 0x00DC
|
||||
#define MSM7200_REG_SFLASHC_BURST_CFG 0x00E0
|
||||
#define MSM7200_REG_ADDR6 0x00E4
|
||||
#define MSM7200_REG_EBI2_ECC_BUF_CFG 0x00F0
|
||||
#define MSM7200_REG_HW_INFO 0x00FC
|
||||
#define MSM7200_REG_FLASH_BUFFER 0x0100
|
||||
#define MSM7200_REG_NAND_MPU_ENABLE 0x100000
|
||||
|
||||
#define MSM7200_CMD_RESET 0x31
|
||||
#define MSM7200_CMD_PAGE_READ 0x32
|
||||
#define MSM7200_CMD_PAGE_READ_ECC 0x33
|
||||
#define MSM7200_CMD_PAGE_READ_ALL 0x34
|
||||
#define MSM7200_CMD_SEQ_PAGE_READ 0x15
|
||||
#define MSM7200_CMD_PRG_PAGE 0x36
|
||||
#define MSM7200_CMD_PRG_PAGE_ECC 0x37
|
||||
#define MSM7200_CMD_PRG_PAGE_ALL 0x39
|
||||
#define MSM7200_CMD_BLOCK_ERASE 0x3A
|
||||
#define MSM7200_CMD_FETCH_ID 0x0B
|
||||
#define MSM7200_CMD_STATUS 0x0C
|
||||
#define MSM7200_CMD_RESET_NAND 0x0D
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_LAST = {26, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_READ_CACHE_SEQ = {25, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_READ_CACHE_NEXT_CMD = {24, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EN_PROGRAM_PAGE_CACHE_NEXT_CMD = {20, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_EXTENDED_FETCH_ID = {19, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_INTR_STATUS = {18, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_ONE_NAND_HOST_CFG = {17, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT_DATA_XFR_SIZE = {7, 0x3ff};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_AUTO_DETECT = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_LAST_PAGE = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_PAGE_ACC = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CMD_OP_CMD = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_NON_PAGE_ACCESS_COMMAND 0
|
||||
#define MSM7200_NAND_FLASH_CMD_PAGE_ACC_PAGE_ACCESS_COMMAND 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_0 0
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_READ_WITH_ECC_SPARE 4
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PAGE_PROGRAM_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_8 8
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESET_NAND_FLASH_DEVICE_OR_ONENAND_REGISTER_WRITE 13
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_E 14
|
||||
#define MSM7200_NAND_FLASH_CMD_OP_CMD_RESERVED_F 15
|
||||
|
||||
bitmask MSM7200_NAND_ADDR0_DEV_ADDR0 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR1_DEV_ADDR1 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_RESET_XFR_STEP_LOAD_DONE_STATUS = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_ONE_NAND_EN = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_DM_EN = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_XFR_STEP2_SAFE_REG_EN_DYNAMICALLY_CHANGING_THE_XFR_STEP2_IS_ENABLED 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_DISABLE 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_PARTIAL_XFR_ENABLE 1
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS0_IS_SELECTED 0
|
||||
#define MSM7200_NAND_FLASH_CHIP_SELECT_NAND_DEV_SEL_NAND_CS1_IS_SELECTED 1
|
||||
|
||||
bitmask MSM7200_NANDC_EXEC_CMD_EXEC_CMD = {0, 0x1};
|
||||
#define MSM7200_NANDC_EXEC_CMD_EXEC_CMD_EXECUTE_THE_COMMAND 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_DEV_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_CODEWORD_CNTR = {12, 0xf};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE = {11, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE = {10, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_AUTO_DETECT_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_MPU_ERROR = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_PROG_ERASE_OP_RESULT = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_READY_BSY_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OP_ERR = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_STATUS_OPER_STATUS = {0, 0xf};
|
||||
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_NOT_A_2K_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_2KBYTE_DEVICE_ENUM_2K_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_NOT_A_512_BYTE_PAGE_DEVICE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_FIELD_512BYTE_DEVICE_ENUM_512_BYTE_PAGE_DEVICE 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_MPU_ERROR_MPU_ERROR_FOR_THE_ACCESS 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_NO_ERROR 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_NANDC_TIMEOUT_ERR_ERROR 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_BUSY 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_READY_BSY_N_EXTERNAL_FLASH_IS_READY 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_IDLE_STATE 0
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_ABORT_TRANSACTION 1
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ 2
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC 3
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PAGE_READ_WITH_ECC_AND_SPARE_DATA 4
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_SEQUENTIAL_PAGE_READ 5
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE 6
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_ECC 7
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESERVED_PROGRAMMING 8
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_PROGRAM_PAGE_WITH_SPARE 9
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_BLOCK_ERASE 10
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_FETCH_ID 11
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_CHECK_STATUS 12
|
||||
#define MSM7200_NAND_FLASH_STATUS_OPER_STATUS_RESET_FLASH_DEVICE 13
|
||||
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_BAD_BLOCK_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_XFR_STEP2_REG_UPDATE_DONE = {9, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_UNCORRECTABLE = {8, 0x1};
|
||||
bitmask MSM7200_NANDC_BUFFER_STATUS_NUM_ERRORS = {0, 0x1f};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SET_RD_MODE_AFTER_STATUS = {31, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_STATUS_BFR_READ = {30, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES = {27, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_SPARE_SIZE_BYTES = {23, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ECC_PARITY_SIZE_BYTES = {19, 0xf};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_UD_SIZE_BYTES = {9, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_CW_PER_PAGE = {6, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES = {3, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES = {0, 0x7};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG0_NUM_ADDR_CYCLES_NO_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__1_CODEWORD_PER_PAGE 0
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__2_CODEWORDS_PER_PAGE 1
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__3_CODEWORDS_PER_PAGE 2
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__4_CODEWORDS_PER_PAGE 3
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__5_CODEWORDS_PER_PAGE 4
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__6_CODEWORDS_PER_PAGE 5
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__7_CODEWORDS_PER_PAGE 6
|
||||
#define MSM7200_NAND_DEV_CFG0_CW_PER_PAGE__8_CODEWORDS_PER_PAGE 7
|
||||
#define MSM7200_NAND_DEV_CFG0_ROW_ADDR_CYCLES_NO_ROW_ADDRESS_CYCLES 0
|
||||
#define MSM7200_NAND_DEV_CFG0_COL_ADDR_CYCLES_NO_COLUMN_ADDRESS_CYCLES 0
|
||||
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_MODE = {28, 0x3};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ENABLE_BCH_ECC = {27, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_DISABLE_ECC_RESET_AFTER_OPDONE = {25, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DECODER_CGC_EN = {24, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_ENCODER_CGC_EN = {23, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP = {17, 0x3f};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA = {16, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_BAD_BLOCK_BYTE_NUM = {6, 0x3ff};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY = {5, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES = {2, 0x7};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_WIDE_FLASH = {1, 0x1};
|
||||
bitmask MSM7200_NAND_DEV_CFG1_ECC_DISABLE = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_2_CLOCK_CYCLE_GAP 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_4_CLOCK_CYCLES_GAP 1
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_6_CLOCK_CYCLES_GAP 2
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_8_CLOCK_CYCLES_GAP 3
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_10_CLOCK_CYCLES_GAP 4
|
||||
#define MSM7200_NAND_DEV_CFG1_WR_RD_BSY_GAP_ENUM_128_CLOCK_CYCLES_GAP 63
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_USER_DATA_AREA 0
|
||||
#define MSM7200_NAND_DEV_CFG1_BAD_BLOCK_IN_SPARE_AREA_IN_SPARE_AREA 1
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ALLOW_CS_DE_ASSERTION 0
|
||||
#define MSM7200_NAND_DEV_CFG1_CS_ACTIVE_BSY_ASSERT_CS_DURING_BUSY 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_1_RECOVERY_CYCLE 0
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_2_RECOVERY_CYCLES 1
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_3_RECOVERY_CYCLES 2
|
||||
#define MSM7200_NAND_DEV_CFG1_NAND_RECOVERY_CYCLES_ENUM_8_RECOVERY_CYCLES 7
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_8_BIT_DATA_BUS 0
|
||||
#define MSM7200_NAND_DEV_CFG1_WIDE_FLASH_ENUM_16_BIT_DATA_BUS 1
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_READ_ID_READ_ID = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_ECC_STATUS = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_READ_STATUS_DEV_STATUS = {0, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_DATA_IN = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT = {16, 0xffff};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ADDR_OUT = {14, 0x3};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_OUT_EN = {13, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN = {10, 0x7};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS5_N = {9, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS4_N = {8, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS3_N = {7, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS2_N = {6, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS1_N = {5, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CS0_N = {4, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_ALE = {3, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_CLE = {2, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_WE_N = {1, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_RE_N = {0, 0x1};
|
||||
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_DONT_READ 0
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_15_0 1
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_CONFIG_DATA_31_16 2
|
||||
#define MSM7200_NAND_FLASH_CONFIG_DATA_IN_EN_WRITE_NAND_FLASH_READ_STATUS_15_0 3
|
||||
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_MODE_CONFIG_ACC = {0, 0x1};
|
||||
bitmask MSM7200_NAND_FLASH_CONFIG_STATUS_CONFIG_MODE = {0, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_ADDR_BUS_HOLD_CYCLE = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_QSC6270_DATA_START_ADDR = {0, 0xffff};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO1 = {14, 0x3f};
|
||||
bitmask MSM7200_FLASH_MACRO1_REG_FLASH_DATA_MACRO0 = {0, 0x3fff};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER = {30, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_STEP1_WAIT = {26, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN = {25, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_DATA_EN = {24, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CE_EN = {23, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_CLE_EN = {22, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN = {21, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WE_EN = {20, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_RE_EN = {19, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_CMD_WIDE = {18, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER = {14, 0x3};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_STEP1_WAIT = {10, 0xf};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN = {9, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_DATA_EN = {8, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CE_EN = {7, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_CLE_EN = {6, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN = {5, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WE_EN = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_RE_EN = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_DATA_WIDE = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_XFR_STEP_EXTA_READ_WAIT = {0, 0x3};
|
||||
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_SIMPLE_STEP 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_CLE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_8_BIT_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_CMD_WIDE_SEND_CMD_ON_16_BIT_BUS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_START 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LOOP_END 2
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_SEQ_STEP_NUMBER_LAST_STEP 3
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_ADDRESS_LOGIC_DISABLED 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_AOUT_EN_DRIVE_ADDRESS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DISABLE_DATA_BUS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_DATA_EN_DRIVE_DATA 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_DE_ASSERT_CHIP_SELECTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CE_EN_ASSERT_CHIP_SELECT 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_CLE_EN_THE_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_ALE_PIN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_DE_ASSERTS 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_RE_EN_LOGIC_ASSERTS 1
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE_8_BIT_DATA_BUS_FOR_DATA 0
|
||||
#define MSM7200_FLASH_XFR_STEP_DATA_WIDE_USE16_BIT_DATA_BUS_FOR_DATA 1
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_START = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_WRITE_ADDR = {16, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_START = {8, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_ERASE_ADDR = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_PARAMETER_PAGE_CODE = {24, 0xff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_SEQ_READ_START_VLD = {4, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_ERASE_START_VLD = {3, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_WRITE_START_VLD = {2, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_STOP_VLD = {1, 0x1};
|
||||
bitmask MSM7200_FLASH_DEV_CMD_VLD_READ_START_VLD = {0, 0x1};
|
||||
|
||||
bitmask MSM7200_EBI2_MISR_SIG_REG_EBI2_MISR_SIG = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR2_DEV_ADDR2 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR3_DEV_ADDR3 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR4_DEV_ADDR4 = {0, 0xffffffff};
|
||||
bitmask MSM7200_NAND_ADDR5_DEV_ADDR5 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_LAST = {24, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_READ_CACHE_SEQ = {16, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD3_WRITE_START_CACHE = {0, 0xff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD4 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD4_GP_CMD3 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD6 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD5_GP_CMD5 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD8 = {16, 0xffff};
|
||||
bitmask MSM7200_FLASH_DEV_CMD6_GP_CMD7 = {0, 0xffff};
|
||||
|
||||
bitmask MSM7200_NAND_ADDR6_DEV_ADDR6 = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_EBI2_ECC_BUF_CFG_NUM_STEPS = {0, 0x3ff};
|
||||
|
||||
bitmask MSM7200_FLASH_BUFF0_ACC_BUFF_DATA = {0, 0xffffffff};
|
||||
|
||||
bitmask MSM7200_SFLASHC_EXEC_CMD_BUSY = {0, 0x1};
|
||||
bitmask MSM7200_SFLASHC_OPER_STATUS = {0, 0xf};
|
||||
|
|
@ -1,87 +1,87 @@
|
|||
#include "onenand.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "controller/controller.h"
|
||||
|
||||
void OneNAND_Ctrl_Wait_Ready(DCCMemory *mem, uint16_t flag) {
|
||||
// Busy assert routines
|
||||
do {
|
||||
wdog_reset();
|
||||
} while ((OneNAND_Ctrl_Reg_Read(mem, O1N_REG_INTERRUPT) & flag) != flag);
|
||||
}
|
||||
|
||||
uint32_t OneNAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
wdog_reset();
|
||||
OneNAND_Pre_Initialize(mem, offset);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_SYS_CFG1, 0x40c0);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS1, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS2, 0x0);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_INTERRUPT, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_COMMAND, O1N_CMD_HOT_RESET);
|
||||
|
||||
OneNAND_Ctrl_Wait_Ready(mem, 0x8000);
|
||||
|
||||
uint16_t mfr_id = OneNAND_Ctrl_Reg_Read(mem, O1N_REG_MANUFACTURER_ID);
|
||||
uint16_t dev_id = OneNAND_Ctrl_Reg_Read(mem, O1N_REG_DEVICE_ID);
|
||||
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->type = MEMTYPE_ONENAND;
|
||||
|
||||
mem->bit_width = 16;
|
||||
uint32_t density = 2 << ((mem->page_size == 4096 ? 4 : 3) + ((dev_id >> 4) & 0xf));
|
||||
|
||||
mem->size = density << 20;
|
||||
mem->block_size = mem->page_size * 0x40;
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
uint32_t OneNAND_Read_Upper(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_INTERRUPT, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_ECC_STATUS, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_BUFFER, (8 << 8)); // First DataRAM
|
||||
|
||||
uint32_t density = 2 << ((mem->page_size == 4096 ? 4 : 3) + ((mem->device_id >> 4) & 0xf));
|
||||
uint32_t addr1_mask = ((mem->device_id & 8) ? (density << 2) : (density << 3)) - 1;
|
||||
uint32_t ddp_access = (mem->device_id & 8) && ((page >> 6) >= (density << 2));
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS1, (ddp_access ? 0x8000 : 0) | ((page >> 6) & addr1_mask));
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS2, ddp_access ? 0x8000 : 0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS8, (page & 63) << 2);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_COMMAND, O1N_CMD_READ);
|
||||
OneNAND_Ctrl_Wait_Ready(mem, 0x8080);
|
||||
|
||||
OneNAND_Ctrl_Get_Data(mem, page_buf, spare_buf, mem->page_size, mem->page_size >> 5);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN OneNAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
uint32_t spare_offset = size;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = OneNAND_Read_Upper(mem, dest + page_offset, dest + spare_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
spare_offset += mem->page_size >> 5;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = spare_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver onenand_controller = {
|
||||
.initialize = OneNAND_Probe,
|
||||
.read = OneNAND_Read
|
||||
#include "onenand.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "controller/controller.h"
|
||||
|
||||
void OneNAND_Ctrl_Wait_Ready(DCCMemory *mem, uint16_t flag) {
|
||||
// Busy assert routines
|
||||
do {
|
||||
wdog_reset();
|
||||
} while ((OneNAND_Ctrl_Reg_Read(mem, O1N_REG_INTERRUPT) & flag) != flag);
|
||||
}
|
||||
|
||||
uint32_t OneNAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
wdog_reset();
|
||||
OneNAND_Pre_Initialize(mem, offset);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_SYS_CFG1, 0x40c0);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS1, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS2, 0x0);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_INTERRUPT, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_COMMAND, O1N_CMD_HOT_RESET);
|
||||
|
||||
OneNAND_Ctrl_Wait_Ready(mem, 0x8000);
|
||||
|
||||
uint16_t mfr_id = OneNAND_Ctrl_Reg_Read(mem, O1N_REG_MANUFACTURER_ID);
|
||||
uint16_t dev_id = OneNAND_Ctrl_Reg_Read(mem, O1N_REG_DEVICE_ID);
|
||||
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->type = MEMTYPE_ONENAND;
|
||||
|
||||
mem->bit_width = 16;
|
||||
uint32_t density = 2 << ((mem->page_size == 4096 ? 4 : 3) + ((dev_id >> 4) & 0xf));
|
||||
|
||||
mem->size = density << 20;
|
||||
mem->block_size = mem->page_size * 0x40;
|
||||
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
uint32_t OneNAND_Read_Upper(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_INTERRUPT, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_ECC_STATUS, 0x0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_BUFFER, (8 << 8)); // First DataRAM
|
||||
|
||||
uint32_t density = 2 << ((mem->page_size == 4096 ? 4 : 3) + ((mem->device_id >> 4) & 0xf));
|
||||
uint32_t addr1_mask = ((mem->device_id & 8) ? (density << 2) : (density << 3)) - 1;
|
||||
uint32_t ddp_access = (mem->device_id & 8) && ((page >> 6) >= (density << 2));
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS1, (ddp_access ? 0x8000 : 0) | ((page >> 6) & addr1_mask));
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS2, ddp_access ? 0x8000 : 0);
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_START_ADDRESS8, (page & 63) << 2);
|
||||
|
||||
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_COMMAND, O1N_CMD_READ);
|
||||
OneNAND_Ctrl_Wait_Ready(mem, 0x8080);
|
||||
|
||||
OneNAND_Ctrl_Get_Data(mem, page_buf, spare_buf, mem->page_size, mem->page_size >> 5);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN OneNAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
uint32_t spare_offset = size;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = OneNAND_Read_Upper(mem, dest + page_offset, dest + spare_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
spare_offset += mem->page_size >> 5;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = spare_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver onenand_controller = {
|
||||
.initialize = OneNAND_Probe,
|
||||
.read = OneNAND_Read
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
extern Driver onenand_controller;
|
||||
|
|
@ -1,49 +1,49 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t dev_id;
|
||||
uint32_t page_size;
|
||||
uint32_t chip_size;
|
||||
uint32_t block_size;
|
||||
uint32_t bits;
|
||||
} superand_info;
|
||||
|
||||
static superand_info flash_ids[] = {
|
||||
/* 16MB */
|
||||
{0x51, 0x200, 0x01000000, 0x4000, 8},
|
||||
{0x52, 0x200, 0x01000000, 0x4000, 8},
|
||||
{0x53, 0x200, 0x01000000, 0x4000, 16},
|
||||
{0x54, 0x200, 0x01000000, 0x4000, 16},
|
||||
|
||||
/* 32MB */
|
||||
// {0x48, 0x200, 0x02000000, 0x4000, 8},
|
||||
{0x49, 0x200, 0x02000000, 0x4000, 8},
|
||||
{0x4a, 0x200, 0x02000000, 0x4000, 16},
|
||||
// {0x4b, 0x200, 0x02000000, 0x4000, 16},
|
||||
|
||||
/* 64MB */
|
||||
{0x58, 0x200, 0x04000000, 0x4000, 8},
|
||||
// {0x59, 0x200, 0x04000000, 0x4000, 8},
|
||||
// {0x5a, 0x200, 0x04000000, 0x4000, 16},
|
||||
{0x5b, 0x200, 0x04000000, 0x4000, 16},
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SUPERAND_CMD_READ = 0x0,
|
||||
SUPERAND_CMD_READ_SEQ = 0xF,
|
||||
SUPERAND_CMD_PAGEPROG = 0x10,
|
||||
SUPERAND_CMD_EXTMODE = 0x11,
|
||||
SUPERAND_CMD_REWRITE = 0x1F,
|
||||
SUPERAND_CMD_ERASE1 = 0x60,
|
||||
SUPERAND_CMD_STATUS = 0x70,
|
||||
SUPERAND_CMD_SEQIN = 0x80,
|
||||
SUPERAND_CMD_READID = 0x90,
|
||||
SUPERAND_CMD_STANDBY_SET = 0xC0,
|
||||
SUPERAND_CMD_STANDBY_REL = 0xC1,
|
||||
SUPERAND_CMD_ERASE2 = 0xD0,
|
||||
SUPERAND_CMD_READ_EXIT = 0xF0
|
||||
} SuperANDCommands;
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Probe(DCCMemory *mem);
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t dev_id;
|
||||
uint32_t page_size;
|
||||
uint32_t chip_size;
|
||||
uint32_t block_size;
|
||||
uint32_t bits;
|
||||
} superand_info;
|
||||
|
||||
static superand_info flash_ids[] = {
|
||||
/* 16MB */
|
||||
{0x51, 0x200, 0x01000000, 0x4000, 8},
|
||||
{0x52, 0x200, 0x01000000, 0x4000, 8},
|
||||
{0x53, 0x200, 0x01000000, 0x4000, 16},
|
||||
{0x54, 0x200, 0x01000000, 0x4000, 16},
|
||||
|
||||
/* 32MB */
|
||||
// {0x48, 0x200, 0x02000000, 0x4000, 8},
|
||||
{0x49, 0x200, 0x02000000, 0x4000, 8},
|
||||
{0x4a, 0x200, 0x02000000, 0x4000, 16},
|
||||
// {0x4b, 0x200, 0x02000000, 0x4000, 16},
|
||||
|
||||
/* 64MB */
|
||||
{0x58, 0x200, 0x04000000, 0x4000, 8},
|
||||
// {0x59, 0x200, 0x04000000, 0x4000, 8},
|
||||
// {0x5a, 0x200, 0x04000000, 0x4000, 16},
|
||||
{0x5b, 0x200, 0x04000000, 0x4000, 16},
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SUPERAND_CMD_READ = 0x0,
|
||||
SUPERAND_CMD_READ_SEQ = 0xF,
|
||||
SUPERAND_CMD_PAGEPROG = 0x10,
|
||||
SUPERAND_CMD_EXTMODE = 0x11,
|
||||
SUPERAND_CMD_REWRITE = 0x1F,
|
||||
SUPERAND_CMD_ERASE1 = 0x60,
|
||||
SUPERAND_CMD_STATUS = 0x70,
|
||||
SUPERAND_CMD_SEQIN = 0x80,
|
||||
SUPERAND_CMD_READID = 0x90,
|
||||
SUPERAND_CMD_STANDBY_SET = 0xC0,
|
||||
SUPERAND_CMD_STANDBY_REL = 0xC1,
|
||||
SUPERAND_CMD_ERASE2 = 0xD0,
|
||||
SUPERAND_CMD_READ_EXIT = 0xF0
|
||||
} SuperANDCommands;
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Probe(DCCMemory *mem);
|
||||
DCC_RETURN SuperAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint32_t page);
|
||||
|
|
@ -1,83 +1,83 @@
|
|||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
void SuperAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
void SuperAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint16_t SuperAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SuperAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t SuperAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READID);
|
||||
SuperAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = SuperAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = SuperAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_SUPERAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_SUPERAND) return DCC_PROBE_ERROR;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READ);
|
||||
|
||||
uint32_t sand_page = page & 3;
|
||||
uint32_t sand_sector = page >> 2;
|
||||
|
||||
SuperAND_Ctrl_Address_Write(0);
|
||||
SuperAND_Ctrl_Address_Write(mem->bit_width == 8 ? (sand_page << 1) : sand_page);
|
||||
SuperAND_Ctrl_Address_Write(sand_sector);
|
||||
SuperAND_Ctrl_Address_Write(sand_sector >> 8);
|
||||
|
||||
SuperAND_Ctrl_Wait_Ready();
|
||||
if (!SuperAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = SuperAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)SuperAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READ_EXIT);
|
||||
return DCC_OK;
|
||||
/* Nand controller template */
|
||||
#include "controller.h"
|
||||
|
||||
void SuperAND_Ctrl_Command_Write(uint8_t cmd) {
|
||||
// Write command routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
void SuperAND_Ctrl_Address_Write(uint8_t addr) {
|
||||
// Write address routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint16_t SuperAND_Ctrl_Data_Read() {
|
||||
// Data read routines
|
||||
wdog_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SuperAND_Ctrl_Wait_Ready() {
|
||||
// Busy assert routines
|
||||
wdog_reset();
|
||||
}
|
||||
|
||||
uint32_t SuperAND_Ctrl_Check_Status() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Probe(DCCMemory *mem) {
|
||||
wdog_reset();
|
||||
mem->type = MEMTYPE_NONE;
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READID);
|
||||
SuperAND_Ctrl_Address_Write(0x0);
|
||||
|
||||
uint16_t mfr_id = SuperAND_Ctrl_Data_Read();
|
||||
uint16_t dev_id = SuperAND_Ctrl_Data_Read();
|
||||
|
||||
for (int i = 0; flash_ids[i].dev_id; i++) {
|
||||
if (dev_id == (uint16_t)flash_ids[i].dev_id) {
|
||||
mem->device_id = dev_id;
|
||||
mem->manufacturer = mfr_id;
|
||||
mem->bit_width = flash_ids[i].bits;
|
||||
mem->block_size = flash_ids[i].block_size;
|
||||
mem->page_size = flash_ids[i].page_size;
|
||||
mem->size = flash_ids[i].chip_size;
|
||||
mem->type = MEMTYPE_SUPERAND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mem->type != MEMTYPE_SUPERAND) return DCC_PROBE_ERROR;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Ctrl_Read(DCCMemory *mem, uint8_t *page_buf, uint32_t page) {
|
||||
wdog_reset();
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READ);
|
||||
|
||||
uint32_t sand_page = page & 3;
|
||||
uint32_t sand_sector = page >> 2;
|
||||
|
||||
SuperAND_Ctrl_Address_Write(0);
|
||||
SuperAND_Ctrl_Address_Write(mem->bit_width == 8 ? (sand_page << 1) : sand_page);
|
||||
SuperAND_Ctrl_Address_Write(sand_sector);
|
||||
SuperAND_Ctrl_Address_Write(sand_sector >> 8);
|
||||
|
||||
SuperAND_Ctrl_Wait_Ready();
|
||||
if (!SuperAND_Ctrl_Check_Status()) return DCC_READ_ERROR;
|
||||
|
||||
for (int i = 0; i < (mem->page_size >> (mem->bit_width >> 4)); i++) {
|
||||
wdog_reset();
|
||||
if (mem->bit_width == 16) {
|
||||
((uint16_t *)(page_buf))[i] = SuperAND_Ctrl_Data_Read();
|
||||
} else {
|
||||
page_buf[i] = (uint8_t)SuperAND_Ctrl_Data_Read();
|
||||
}
|
||||
}
|
||||
|
||||
SuperAND_Ctrl_Command_Write(SUPERAND_CMD_READ_EXIT);
|
||||
return DCC_OK;
|
||||
}
|
||||
|
|
@ -1,31 +1,31 @@
|
|||
#include "superand.h"
|
||||
#include "controller/controller.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN SuperAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
return SuperAND_Ctrl_Probe(mem);
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = SuperAND_Ctrl_Read(mem, dest + page_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = page_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver superand_controller = {
|
||||
.initialize = SuperAND_Probe,
|
||||
.read = SuperAND_Read
|
||||
#include "superand.h"
|
||||
#include "controller/controller.h"
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
DCC_RETURN SuperAND_Probe(DCCMemory *mem, uint32_t offset) {
|
||||
return SuperAND_Ctrl_Probe(mem);
|
||||
}
|
||||
|
||||
DCC_RETURN SuperAND_Read(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size) {
|
||||
uint32_t page_offset = 0;
|
||||
DCC_RETURN ret_code;
|
||||
|
||||
if (size & (mem->page_size - 1)) return DCC_INVALID_ARGS;
|
||||
|
||||
do {
|
||||
ret_code = SuperAND_Ctrl_Read(mem, dest + page_offset, offset >> DN_Log2(mem->page_size));
|
||||
if (ret_code != DCC_OK) return ret_code;
|
||||
|
||||
offset += mem->page_size;
|
||||
page_offset += mem->page_size;
|
||||
size -= mem->page_size;
|
||||
} while (size);
|
||||
|
||||
*dest_size = page_offset;
|
||||
return DCC_OK;
|
||||
}
|
||||
|
||||
Driver superand_controller = {
|
||||
.initialize = SuperAND_Probe,
|
||||
.read = SuperAND_Read
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
#pragma once
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
|
||||
extern Driver superand_controller;
|
||||
14
lz4/lz4_fs.c
14
lz4/lz4_fs.c
|
|
@ -1,8 +1,8 @@
|
|||
#include <memory.h>
|
||||
|
||||
#define LZ4_FREESTANDING 1
|
||||
#define LZ4_memcpy memcpy
|
||||
#define LZ4_memset memset
|
||||
#define LZ4_memmove memmove
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#define LZ4_FREESTANDING 1
|
||||
#define LZ4_memcpy memcpy
|
||||
#define LZ4_memset memset
|
||||
#define LZ4_memmove memmove
|
||||
|
||||
#include "lz4.c"
|
||||
488
main.c
488
main.c
|
|
@ -1,245 +1,245 @@
|
|||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "flash/cfi/cfi.h"
|
||||
#include "devices.h"
|
||||
|
||||
typedef DCC_RETURN DCC_INIT_PTR(DCCMemory *mem, uint32_t offset);
|
||||
typedef DCC_RETURN DCC_READ_PTR(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size);
|
||||
|
||||
static uint8_t compBuf[DCC_BUFFER_SIZE + 0x2000];
|
||||
static uint8_t rawBuf[DCC_BUFFER_SIZE + 0x2000];
|
||||
#ifdef DCC_TESTING
|
||||
extern uint32_t DCC_COMPRESS_MEMCPY(uint32_t algo, uint32_t src_offset, uint32_t size, uint8_t *dest);
|
||||
void *absolute_to_relative(void* ptr) { return ptr; };
|
||||
#else
|
||||
extern void *absolute_to_relative(void *ptr);
|
||||
#endif
|
||||
|
||||
// dcc code
|
||||
void dcc_main(uint32_t BaseAddress1, uint32_t BaseAddress2, uint32_t BaseAddress3) {
|
||||
DCCMemory mem[16] = { 0 };
|
||||
uint8_t mem_has_spare[16] = { 0 };
|
||||
uint32_t BUF_INIT[512];
|
||||
uint32_t dcc_init_offset = 0;
|
||||
uint32_t ext_mem;
|
||||
Driver *devBase;
|
||||
DCC_RETURN res;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!devices[i].driver) break;
|
||||
devBase = (Driver *)absolute_to_relative(devices[i].driver);
|
||||
res = ((DCC_INIT_PTR *)absolute_to_relative(devBase->initialize))(&mem[i], devices[i].base_offset);
|
||||
if (res != DCC_OK) mem[i].type = MEMTYPE_NONE;
|
||||
|
||||
switch (mem[i].type) {
|
||||
case MEMTYPE_NOR:
|
||||
case MEMTYPE_SUPERAND:
|
||||
ext_mem = DCC_MEM_EXTENDED(1, mem[i].page_size, mem[i].block_size, mem[i].size >> 20);
|
||||
mem_has_spare[i] = 0;
|
||||
WRITE_EXTMEM:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (ext_mem << 16);
|
||||
BUF_INIT[dcc_init_offset++] = mem[i].manufacturer | (mem[i].device_id << 16);
|
||||
BUF_INIT[dcc_init_offset++] = ext_mem;
|
||||
break;
|
||||
|
||||
case MEMTYPE_NAND:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (mem[i].page_size << 16);
|
||||
BUF_INIT[dcc_init_offset++] = mem[i].manufacturer | (mem[i].device_id << 16);
|
||||
mem_has_spare[i] = 1;
|
||||
break;
|
||||
|
||||
case MEMTYPE_ONENAND:
|
||||
case MEMTYPE_AND:
|
||||
case MEMTYPE_AG_AND:
|
||||
ext_mem = DCC_MEM_EXTENDED(0, mem[i].page_size, mem[i].block_size, mem[i].size >> 20);
|
||||
mem_has_spare[i] = 1;
|
||||
goto WRITE_EXTMEM;
|
||||
|
||||
default:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (DCC_MEM_NONE << 16);
|
||||
BUF_INIT[dcc_init_offset++] = 0;
|
||||
mem_has_spare[i] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (DCC_MEM_BUFFER(0) << 16);
|
||||
BUF_INIT[dcc_init_offset++] = DCC_BUFFER_SIZE;
|
||||
|
||||
DN_Packet_Send((uint8_t *)BUF_INIT, dcc_init_offset << 2);
|
||||
|
||||
uint32_t dcc_comp_packet_size;
|
||||
uint32_t flashIndex;
|
||||
uint32_t srcOffset;
|
||||
uint32_t srcSize;
|
||||
uint32_t destSize;
|
||||
|
||||
while (1) {
|
||||
wdog_reset();
|
||||
uint32_t cmd = DN_Packet_DCC_Read();
|
||||
|
||||
switch (cmd & 0xff) {
|
||||
case CMD_CONFIGURE:
|
||||
for (int c = 0; c < (cmd >> 0x10); c += 4) {
|
||||
DN_Packet_DCC_Read();
|
||||
}
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x38, 0x6));
|
||||
break;
|
||||
|
||||
case CMD_GETINFO:
|
||||
DN_Packet_Send((uint8_t *)BUF_INIT, dcc_init_offset << 2);
|
||||
break;
|
||||
|
||||
case CMD_GETMEMSIZE:
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
if (flashIndex == 0) {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x21, 0));
|
||||
} else if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x21, mem[flashIndex - 1].size >> 20));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_READ:
|
||||
srcOffset = DN_Packet_DCC_Read();
|
||||
srcSize = DN_Packet_DCC_Read();
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
uint8_t algo = (cmd >> 24) & 0xff;
|
||||
|
||||
if (srcSize > DCC_BUFFER_SIZE) {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flashIndex == 0) {
|
||||
Jump_Read_NOR:
|
||||
#ifndef DCC_TESTING
|
||||
switch (algo) {
|
||||
case CMD_READ_COMP_NONE:
|
||||
dcc_comp_packet_size = DN_Packet_CompressNone((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
|
||||
case CMD_READ_COMP_RLE:
|
||||
dcc_comp_packet_size = DN_Packet_Compress((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
|
||||
#if HAVE_MINILZO
|
||||
case CMD_READ_COMP_LZO:
|
||||
dcc_comp_packet_size = DN_Packet_Compress2((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
case CMD_READ_COMP_LZ4:
|
||||
dcc_comp_packet_size = DN_Packet_Compress3((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
dcc_comp_packet_size = DCC_COMPRESS_MEMCPY(algo, srcOffset, srcSize, compBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_Send(compBuf, dcc_comp_packet_size);
|
||||
} else if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
switch (mem[flashIndex - 1].type) {
|
||||
case MEMTYPE_NAND:
|
||||
case MEMTYPE_ONENAND:
|
||||
case MEMTYPE_SUPERAND:
|
||||
case MEMTYPE_AND:
|
||||
case MEMTYPE_AG_AND:
|
||||
devBase = (Driver *)absolute_to_relative(devices[flashIndex - 1].driver);
|
||||
res = ((DCC_READ_PTR *)absolute_to_relative(devBase->read))(&mem[flashIndex - 1], srcOffset, srcSize, rawBuf, &destSize);
|
||||
if (res != DCC_OK) {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(res));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (algo) {
|
||||
case CMD_READ_COMP_NONE:
|
||||
dcc_comp_packet_size = DN_Packet_CompressNone(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
|
||||
case CMD_READ_COMP_RLE:
|
||||
dcc_comp_packet_size = DN_Packet_Compress(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
|
||||
#if HAVE_MINILZO
|
||||
case CMD_READ_COMP_LZO:
|
||||
dcc_comp_packet_size = DN_Packet_Compress2(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
case CMD_READ_COMP_LZ4:
|
||||
dcc_comp_packet_size = DN_Packet_Compress3(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
|
||||
DN_Packet_Send(compBuf, dcc_comp_packet_size);
|
||||
break;
|
||||
case MEMTYPE_NOR:
|
||||
default:
|
||||
srcOffset += mem[flashIndex - 1].base_offset;
|
||||
goto Jump_Read_NOR;
|
||||
}
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_FLASH_NOENT));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CMD_ERASE:
|
||||
srcOffset = DN_Packet_DCC_Read();
|
||||
srcSize = DN_Packet_DCC_Read();
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
|
||||
if (flashIndex == 0) flashIndex = 1;
|
||||
|
||||
if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
// TODO: Erasing
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_WPROT_ERROR, flashIndex));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_WRITE:
|
||||
uint32_t pAddrStart = DN_Packet_DCC_Read();
|
||||
uint32_t dataPackN = DN_Packet_DCC_Read();
|
||||
uint8_t progType = (cmd >> 8) & 0x7f;
|
||||
uint8_t useECC = (cmd >> 8) & 0x80;
|
||||
|
||||
flashIndex = (cmd >> 16) & 0xff;
|
||||
|
||||
if (flashIndex == 0) flashIndex = 1;
|
||||
|
||||
if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
if (dataPackN == CMD_WRITE_COMP_NONE) {
|
||||
if (progType & 2) DN_Packet_Read(rawBuf, mem[flashIndex - 1].block_size);
|
||||
if ((progType & 1) && mem_has_spare[flashIndex - 1]) DN_Packet_Read(rawBuf + mem[flashIndex - 1].block_size, mem[flashIndex - 1].block_size >> 5);
|
||||
} else {
|
||||
uint32_t comp_len = DN_Packet_DCC_Read();
|
||||
DN_Packet_Read(compBuf, ALIGN4(comp_len));
|
||||
}
|
||||
uint32_t checksum = DN_Packet_DCC_Read();
|
||||
// TODO: Writing
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_WPROT_ERROR, flashIndex));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(DCC_BAD_COMMAND(cmd & 0xff));
|
||||
}
|
||||
}
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include "flash/cfi/cfi.h"
|
||||
#include "devices.h"
|
||||
|
||||
typedef DCC_RETURN DCC_INIT_PTR(DCCMemory *mem, uint32_t offset);
|
||||
typedef DCC_RETURN DCC_READ_PTR(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size);
|
||||
|
||||
static uint8_t compBuf[DCC_BUFFER_SIZE + 0x2000];
|
||||
static uint8_t rawBuf[DCC_BUFFER_SIZE + 0x2000];
|
||||
#ifdef DCC_TESTING
|
||||
extern uint32_t DCC_COMPRESS_MEMCPY(uint32_t algo, uint32_t src_offset, uint32_t size, uint8_t *dest);
|
||||
void *absolute_to_relative(void* ptr) { return ptr; };
|
||||
#else
|
||||
extern void *absolute_to_relative(void *ptr);
|
||||
#endif
|
||||
|
||||
// dcc code
|
||||
void dcc_main(uint32_t BaseAddress1, uint32_t BaseAddress2, uint32_t BaseAddress3) {
|
||||
DCCMemory mem[16] = { 0 };
|
||||
uint8_t mem_has_spare[16] = { 0 };
|
||||
uint32_t BUF_INIT[512];
|
||||
uint32_t dcc_init_offset = 0;
|
||||
uint32_t ext_mem;
|
||||
Driver *devBase;
|
||||
DCC_RETURN res;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!devices[i].driver) break;
|
||||
devBase = (Driver *)absolute_to_relative(devices[i].driver);
|
||||
res = ((DCC_INIT_PTR *)absolute_to_relative(devBase->initialize))(&mem[i], devices[i].base_offset);
|
||||
if (res != DCC_OK) mem[i].type = MEMTYPE_NONE;
|
||||
|
||||
switch (mem[i].type) {
|
||||
case MEMTYPE_NOR:
|
||||
case MEMTYPE_SUPERAND:
|
||||
ext_mem = DCC_MEM_EXTENDED(1, mem[i].page_size, mem[i].block_size, mem[i].size >> 20);
|
||||
mem_has_spare[i] = 0;
|
||||
WRITE_EXTMEM:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (ext_mem << 16);
|
||||
BUF_INIT[dcc_init_offset++] = mem[i].manufacturer | (mem[i].device_id << 16);
|
||||
BUF_INIT[dcc_init_offset++] = ext_mem;
|
||||
break;
|
||||
|
||||
case MEMTYPE_NAND:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (mem[i].page_size << 16);
|
||||
BUF_INIT[dcc_init_offset++] = mem[i].manufacturer | (mem[i].device_id << 16);
|
||||
mem_has_spare[i] = 1;
|
||||
break;
|
||||
|
||||
case MEMTYPE_ONENAND:
|
||||
case MEMTYPE_AND:
|
||||
case MEMTYPE_AG_AND:
|
||||
ext_mem = DCC_MEM_EXTENDED(0, mem[i].page_size, mem[i].block_size, mem[i].size >> 20);
|
||||
mem_has_spare[i] = 1;
|
||||
goto WRITE_EXTMEM;
|
||||
|
||||
default:
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (DCC_MEM_NONE << 16);
|
||||
BUF_INIT[dcc_init_offset++] = 0;
|
||||
mem_has_spare[i] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BUF_INIT[dcc_init_offset++] = DCC_MEM_OK | (DCC_MEM_BUFFER(0) << 16);
|
||||
BUF_INIT[dcc_init_offset++] = DCC_BUFFER_SIZE;
|
||||
|
||||
DN_Packet_Send((uint8_t *)BUF_INIT, dcc_init_offset << 2);
|
||||
|
||||
uint32_t dcc_comp_packet_size;
|
||||
uint32_t flashIndex;
|
||||
uint32_t srcOffset;
|
||||
uint32_t srcSize;
|
||||
uint32_t destSize;
|
||||
|
||||
while (1) {
|
||||
wdog_reset();
|
||||
uint32_t cmd = DN_Packet_DCC_Read();
|
||||
|
||||
switch (cmd & 0xff) {
|
||||
case CMD_CONFIGURE:
|
||||
for (int c = 0; c < (cmd >> 0x10); c += 4) {
|
||||
DN_Packet_DCC_Read();
|
||||
}
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x38, 0x6));
|
||||
break;
|
||||
|
||||
case CMD_GETINFO:
|
||||
DN_Packet_Send((uint8_t *)BUF_INIT, dcc_init_offset << 2);
|
||||
break;
|
||||
|
||||
case CMD_GETMEMSIZE:
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
if (flashIndex == 0) {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x21, 0));
|
||||
} else if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(0x21, mem[flashIndex - 1].size >> 20));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_READ:
|
||||
srcOffset = DN_Packet_DCC_Read();
|
||||
srcSize = DN_Packet_DCC_Read();
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
uint8_t algo = (cmd >> 24) & 0xff;
|
||||
|
||||
if (srcSize > DCC_BUFFER_SIZE) {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flashIndex == 0) {
|
||||
Jump_Read_NOR:
|
||||
#ifndef DCC_TESTING
|
||||
switch (algo) {
|
||||
case CMD_READ_COMP_NONE:
|
||||
dcc_comp_packet_size = DN_Packet_CompressNone((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
|
||||
case CMD_READ_COMP_RLE:
|
||||
dcc_comp_packet_size = DN_Packet_Compress((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
|
||||
#if HAVE_MINILZO
|
||||
case CMD_READ_COMP_LZO:
|
||||
dcc_comp_packet_size = DN_Packet_Compress2((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
case CMD_READ_COMP_LZ4:
|
||||
dcc_comp_packet_size = DN_Packet_Compress3((uint8_t *)srcOffset, srcSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
dcc_comp_packet_size = DCC_COMPRESS_MEMCPY(algo, srcOffset, srcSize, compBuf);
|
||||
#endif
|
||||
|
||||
DN_Packet_Send(compBuf, dcc_comp_packet_size);
|
||||
} else if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
switch (mem[flashIndex - 1].type) {
|
||||
case MEMTYPE_NAND:
|
||||
case MEMTYPE_ONENAND:
|
||||
case MEMTYPE_SUPERAND:
|
||||
case MEMTYPE_AND:
|
||||
case MEMTYPE_AG_AND:
|
||||
devBase = (Driver *)absolute_to_relative(devices[flashIndex - 1].driver);
|
||||
res = ((DCC_READ_PTR *)absolute_to_relative(devBase->read))(&mem[flashIndex - 1], srcOffset, srcSize, rawBuf, &destSize);
|
||||
if (res != DCC_OK) {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(res));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (algo) {
|
||||
case CMD_READ_COMP_NONE:
|
||||
dcc_comp_packet_size = DN_Packet_CompressNone(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
|
||||
case CMD_READ_COMP_RLE:
|
||||
dcc_comp_packet_size = DN_Packet_Compress(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
|
||||
#if HAVE_MINILZO
|
||||
case CMD_READ_COMP_LZO:
|
||||
dcc_comp_packet_size = DN_Packet_Compress2(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAVE_LZ4
|
||||
case CMD_READ_COMP_LZ4:
|
||||
dcc_comp_packet_size = DN_Packet_Compress3(rawBuf, destSize, compBuf);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_INVALID_ARGS));
|
||||
continue;
|
||||
}
|
||||
|
||||
DN_Packet_Send(compBuf, dcc_comp_packet_size);
|
||||
break;
|
||||
case MEMTYPE_NOR:
|
||||
default:
|
||||
srcOffset += mem[flashIndex - 1].base_offset;
|
||||
goto Jump_Read_NOR;
|
||||
}
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_READ_RESP_FAIL(DCC_FLASH_NOENT));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CMD_ERASE:
|
||||
srcOffset = DN_Packet_DCC_Read();
|
||||
srcSize = DN_Packet_DCC_Read();
|
||||
flashIndex = (cmd >> 8) & 0xff;
|
||||
|
||||
if (flashIndex == 0) flashIndex = 1;
|
||||
|
||||
if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
// TODO: Erasing
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_WPROT_ERROR, flashIndex));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_WRITE:
|
||||
uint32_t pAddrStart = DN_Packet_DCC_Read();
|
||||
uint32_t dataPackN = DN_Packet_DCC_Read();
|
||||
uint8_t progType = (cmd >> 8) & 0x7f;
|
||||
uint8_t useECC = (cmd >> 8) & 0x80;
|
||||
|
||||
flashIndex = (cmd >> 16) & 0xff;
|
||||
|
||||
if (flashIndex == 0) flashIndex = 1;
|
||||
|
||||
if (flashIndex < 0x11 && mem[flashIndex - 1].type != MEMTYPE_NONE) {
|
||||
if (dataPackN == CMD_WRITE_COMP_NONE) {
|
||||
if (progType & 2) DN_Packet_Read(rawBuf, mem[flashIndex - 1].block_size);
|
||||
if ((progType & 1) && mem_has_spare[flashIndex - 1]) DN_Packet_Read(rawBuf + mem[flashIndex - 1].block_size, mem[flashIndex - 1].block_size >> 5);
|
||||
} else {
|
||||
uint32_t comp_len = DN_Packet_DCC_Read();
|
||||
DN_Packet_Read(compBuf, ALIGN4(comp_len));
|
||||
}
|
||||
uint32_t checksum = DN_Packet_DCC_Read();
|
||||
// TODO: Writing
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_WPROT_ERROR, flashIndex));
|
||||
} else {
|
||||
DN_Packet_Send_One(CMD_WRITE_ERASE_STATUS(DCC_FLASH_NOENT, flashIndex));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DN_Packet_Send_One(DCC_BAD_COMMAND(cmd & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@echo off
|
||||
clang -I . -DDCC_TESTING -DHAVE_MINILZO=1 -DHAVE_LZ4=1 -D_CRT_SECURE_NO_WARNINGS=1 test/test_rle_compress.c dcc/dn_dcc_proto.c minilzo/minilzo.c lz4/lz4_fs.c plat/default.c -o dcc_test_rle.exe
|
||||
clang -I . -DDCC_TESTING -DHAVE_MINILZO=1 -DHAVE_LZ4=1 -D_CRT_SECURE_NO_WARNINGS=1 test/test_dcc_writing_reading.c dcc/dn_dcc_proto.c minilzo/minilzo.c lz4/lz4_fs.c plat/default.c -o dcc_test_wr.exe
|
||||
@echo off
|
||||
clang -I . -DDCC_TESTING -DHAVE_MINILZO=1 -DHAVE_LZ4=1 -D_CRT_SECURE_NO_WARNINGS=1 test/test_rle_compress.c dcc/dn_dcc_proto.c minilzo/minilzo.c lz4/lz4_fs.c plat/default.c -o dcc_test_rle.exe
|
||||
clang -I . -DDCC_TESTING -DHAVE_MINILZO=1 -DHAVE_LZ4=1 -D_CRT_SECURE_NO_WARNINGS=1 test/test_dcc_writing_reading.c dcc/dn_dcc_proto.c minilzo/minilzo.c lz4/lz4_fs.c plat/default.c -o dcc_test_wr.exe
|
||||
clang -I . -DDCC_TESTING -DHAVE_MINILZO=1 -DHAVE_LZ4=1 -D_CRT_SECURE_NO_WARNINGS=1 test/test_dcc_emulate.c test/test_dcc_platform.c main.c dcc/dn_dcc_proto.c dcc/bitutils.c minilzo/minilzo.c lz4/lz4_fs.c plat/default.c flash/cfi/cfi.c flash/mmap/mmap.c -o dcc_test_emu.exe
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U16(0x088a0000, 0x0); // Shut up watchdog
|
||||
WRITE_U16(0x08810000, READ_U16(0x08810000) & ~(1 << 9)); // Disable IRQ also
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x6e
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x088a0000, (READ_U16(0x088a0000) & 0xff00) | DOG_TIMEOUT);
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U16(0x088a0000, 0x0); // Shut up watchdog
|
||||
WRITE_U16(0x08810000, READ_U16(0x08810000) & ~(1 << 9)); // Disable IRQ also
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x6e
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x088a0000, (READ_U16(0x088a0000) & 0xff00) | DOG_TIMEOUT);
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U16(0x40A00018, 0x0); // Shut up watchdog
|
||||
WRITE_U16(0x40A0001C, 0x0); // Shut up interrupts
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U16(0x40A00018, 0x0); // Shut up watchdog
|
||||
WRITE_U16(0x40A0001C, 0x0); // Shut up interrupts
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x30503000, 0x0); // Shut up watchdog
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x3fff
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x30503004, 0x8000 | DOG_TIMEOUT);
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x30503000, 0x0); // Shut up watchdog
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x3fff
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x30503004, 0x8000 | DOG_TIMEOUT);
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x50503000, 0x0); // Shut up watchdog
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x3fff
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x50503004, 0x8000 | DOG_TIMEOUT);
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x50503000, 0x0); // Shut up watchdog
|
||||
}
|
||||
|
||||
#define DOG_TIMEOUT 0x3fff
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
// WRITE_U16(0x50503004, 0x8000 | DOG_TIMEOUT);
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03000600, 0x10);
|
||||
// WRITE_U32(0x03000600, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03000600, 1);
|
||||
WRITE_U32(0x03000600, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03000600, 0x10);
|
||||
// WRITE_U32(0x03000600, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03000600, 1);
|
||||
WRITE_U32(0x03000600, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03000700, 0x10);
|
||||
// WRITE_U32(0x03000700, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03000700, 1);
|
||||
WRITE_U32(0x03000700, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03000700, 0x10);
|
||||
// WRITE_U32(0x03000700, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03000700, 1);
|
||||
WRITE_U32(0x03000700, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03001080, 0x10);
|
||||
// WRITE_U32(0x03001080, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03001080, 1);
|
||||
WRITE_U32(0x03001080, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x03001080, 0x10);
|
||||
// WRITE_U32(0x03001080, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x03001080, 1);
|
||||
WRITE_U32(0x03001080, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x030006d0, 0x10);
|
||||
// WRITE_U32(0x030006d0, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x030006d0, 1);
|
||||
WRITE_U32(0x030006d0, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x030006d0, 0x10);
|
||||
// WRITE_U32(0x030006d0, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x030006d0, 1);
|
||||
WRITE_U32(0x030006d0, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80000700, 0x10);
|
||||
// WRITE_U32(0x80000700, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80000700, 1);
|
||||
WRITE_U32(0x80000700, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80000700, 0x10);
|
||||
// WRITE_U32(0x80000700, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80000700, 1);
|
||||
WRITE_U32(0x80000700, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x14003404, 0x10);
|
||||
// WRITE_U32(0x14003404, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x14003404, 1);
|
||||
WRITE_U32(0x14003404, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x14003404, 0x10);
|
||||
// WRITE_U32(0x14003404, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x14003404, 1);
|
||||
WRITE_U32(0x14003404, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80003404, 0x10);
|
||||
// WRITE_U32(0x80003404, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80003404, 1);
|
||||
WRITE_U32(0x80003404, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80003404, 0x10);
|
||||
// WRITE_U32(0x80003404, 0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80003404, 1);
|
||||
WRITE_U32(0x80003404, 0);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80001b40, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80001b3c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80001b40, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x80001b3c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80000540, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8000053c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80000540, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8000053c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80005410, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8000540c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80005410, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8000540c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0xb8000110, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0xb800010c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0xb8000110, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0xb800010c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x88004010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8800400c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x88004010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8800400c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80018010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8001800c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80018010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8001800c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80034010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8003400c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
// Can alternatively be turned off
|
||||
// WRITE_U32(0x80034010, 1);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
WRITE_U32(0x8003400c, 1);
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x53000000, 0x0);
|
||||
|
||||
WRITE_U32(0x4a000008, 0xffffffff);
|
||||
WRITE_U32(0x4a00001c, 0x000007ff);
|
||||
WRITE_U32(0x4a000000, 0xffffffff);
|
||||
WRITE_U32(0x4a000018, 0x000007ff);
|
||||
WRITE_U32(0x4a000010, 0xffffffff);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x53000000, 0x0);
|
||||
|
||||
WRITE_U32(0x4a000008, 0xffffffff);
|
||||
WRITE_U32(0x4a00001c, 0x000007ff);
|
||||
WRITE_U32(0x4a000000, 0xffffffff);
|
||||
WRITE_U32(0x4a000018, 0x000007ff);
|
||||
WRITE_U32(0x4a000010, 0xffffffff);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x7e004000, 0x0);
|
||||
|
||||
WRITE_U32(0x71200014, 0xffffffff);
|
||||
WRITE_U32(0x71300014, 0xffffffff);
|
||||
|
||||
WRITE_U32(0x7120000c, 0x0);
|
||||
WRITE_U32(0x7130000c, 0x0);
|
||||
|
||||
WRITE_U32(0x71200f00, 0x0);
|
||||
WRITE_U32(0x71300f00, 0x0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
#include "dcc/plat.h"
|
||||
|
||||
void plat_init(void) {
|
||||
// Initialize platform (after CMM, H/W init script, TCL, etc, and Uploading)
|
||||
WRITE_U32(0x7e004000, 0x0);
|
||||
|
||||
WRITE_U32(0x71200014, 0xffffffff);
|
||||
WRITE_U32(0x71300014, 0xffffffff);
|
||||
|
||||
WRITE_U32(0x7120000c, 0x0);
|
||||
WRITE_U32(0x7130000c, 0x0);
|
||||
|
||||
WRITE_U32(0x71200f00, 0x0);
|
||||
WRITE_U32(0x71300f00, 0x0);
|
||||
}
|
||||
|
||||
void wdog_reset(void) {
|
||||
// Reset watchdog (or else, system restarts)
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern void dcc_main(uint32_t BaseAddress1, uint32_t BaseAddress2, uint32_t BaseAddress3);
|
||||
|
||||
int main(void) {
|
||||
dcc_main(0x0, 0x0, 0x0);
|
||||
return 0;
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern void dcc_main(uint32_t BaseAddress1, uint32_t BaseAddress2, uint32_t BaseAddress3);
|
||||
|
||||
int main(void) {
|
||||
dcc_main(0x0, 0x0, 0x0);
|
||||
return 0;
|
||||
}
|
||||
11406
test/test_dcc_platform.c
11406
test/test_dcc_platform.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
#include "dcc/dn_dcc_proto.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
printf("DCC READ OUT: 0x%08X\n", DN_Packet_DCC_Read());
|
||||
DN_Packet_DCC_Send(0x12345678);
|
||||
return 0;
|
||||
#include "dcc/dn_dcc_proto.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
printf("DCC READ OUT: 0x%08X\n", DN_Packet_DCC_Read());
|
||||
DN_Packet_DCC_Send(0x12345678);
|
||||
return 0;
|
||||
}
|
||||
22148
test/test_rle_compress.c
22148
test/test_rle_compress.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,13 @@
|
|||
import re
|
||||
import sys
|
||||
import struct
|
||||
|
||||
if __name__ == "__main__":
|
||||
outFile = open(sys.argv[2], "wb")
|
||||
|
||||
for l in open(sys.argv[1], "r"):
|
||||
#print(l.rstrip())
|
||||
p = re.search(r"([0-9-]*) \(([\S]*)\): ([\S]*) ([\S]*)", l.rstrip())
|
||||
#print(l.rstrip())
|
||||
if not p: continue
|
||||
import re
|
||||
import sys
|
||||
import struct
|
||||
|
||||
if __name__ == "__main__":
|
||||
outFile = open(sys.argv[2], "wb")
|
||||
|
||||
for l in open(sys.argv[1], "r"):
|
||||
#print(l.rstrip())
|
||||
p = re.search(r"([0-9-]*) \(([\S]*)\): ([\S]*) ([\S]*)", l.rstrip())
|
||||
#print(l.rstrip())
|
||||
if not p: continue
|
||||
outFile.write(struct.pack("<lLL", int(p[1]), int(p[3], 16), int(p[4], 16)))
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
import re
|
||||
import sys
|
||||
import struct
|
||||
|
||||
if __name__ == "__main__":
|
||||
outFile = open(sys.argv[2], "wb")
|
||||
m = {"1": -9, "2": -8, "4": -1}
|
||||
|
||||
for l in open(sys.argv[1], "r"):
|
||||
#print(l.rstrip())
|
||||
p = re.search("Write at 0x([0-9a-f]*) ([0-9]*) 0x([0-9a-f]*)", l.rstrip())
|
||||
#print(l.rstrip())
|
||||
if not p: continue
|
||||
import re
|
||||
import sys
|
||||
import struct
|
||||
|
||||
if __name__ == "__main__":
|
||||
outFile = open(sys.argv[2], "wb")
|
||||
m = {"1": -9, "2": -8, "4": -1}
|
||||
|
||||
for l in open(sys.argv[1], "r"):
|
||||
#print(l.rstrip())
|
||||
p = re.search("Write at 0x([0-9a-f]*) ([0-9]*) 0x([0-9a-f]*)", l.rstrip())
|
||||
#print(l.rstrip())
|
||||
if not p: continue
|
||||
outFile.write(struct.pack("<lLL", m[p[2]], int(p[1], 16), int(p[3], 16)))
|
||||
|
|
@ -1,54 +1,54 @@
|
|||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = open(sys.argv[1], "rb")
|
||||
|
||||
pkTable = [
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
|
||||
0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
|
||||
0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
|
||||
0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
|
||||
0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
|
||||
0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
|
||||
0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
|
||||
0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
|
||||
0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
|
||||
0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
|
||||
0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
|
||||
0x3F, 0xBF, 0x7F, 0xFF
|
||||
]
|
||||
|
||||
outb = bytearray()
|
||||
|
||||
while True:
|
||||
temp = a.read(5)
|
||||
if len(temp) == 0: break
|
||||
ac = ((temp[0] << 0x10) | (temp[1] << 0x18) | temp[2] | temp[3] << 8) * 8
|
||||
flag = temp[4]
|
||||
|
||||
ba = pkTable[(ac >> 0x18) & 0xff]
|
||||
bb = pkTable[(ac >> 0x10) & 0xff]
|
||||
bc = pkTable[(ac >> 0x8) & 0xff]
|
||||
bd = pkTable[(ac & 0xff) | ((flag >> 1) & 7)]
|
||||
|
||||
# print(hex(ba))
|
||||
# print(hex(bb))
|
||||
# print(hex(bc))
|
||||
# print(hex(bd))
|
||||
|
||||
out = ba | (bb << 8) | (bc << 16) | (bd << 24)
|
||||
outb += bytes([ba, bb, bc, bd])
|
||||
|
||||
print(f"0x{out:08x}")
|
||||
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
a = open(sys.argv[1], "rb")
|
||||
|
||||
pkTable = [
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
|
||||
0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
|
||||
0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
|
||||
0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
|
||||
0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
|
||||
0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
|
||||
0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
|
||||
0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
|
||||
0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
|
||||
0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
|
||||
0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
|
||||
0x3F, 0xBF, 0x7F, 0xFF
|
||||
]
|
||||
|
||||
outb = bytearray()
|
||||
|
||||
while True:
|
||||
temp = a.read(5)
|
||||
if len(temp) == 0: break
|
||||
ac = ((temp[0] << 0x10) | (temp[1] << 0x18) | temp[2] | temp[3] << 8) * 8
|
||||
flag = temp[4]
|
||||
|
||||
ba = pkTable[(ac >> 0x18) & 0xff]
|
||||
bb = pkTable[(ac >> 0x10) & 0xff]
|
||||
bc = pkTable[(ac >> 0x8) & 0xff]
|
||||
bd = pkTable[(ac & 0xff) | ((flag >> 1) & 7)]
|
||||
|
||||
# print(hex(ba))
|
||||
# print(hex(bb))
|
||||
# print(hex(bc))
|
||||
# print(hex(bd))
|
||||
|
||||
out = ba | (bb << 8) | (bc << 16) | (bd << 24)
|
||||
outb += bytes([ba, bb, bc, bd])
|
||||
|
||||
print(f"0x{out:08x}")
|
||||
|
||||
open(sys.argv[2], "wb").write(outb)
|
||||
|
|
@ -1,210 +1,210 @@
|
|||
import struct
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
|
||||
ip = 0
|
||||
labels = {}
|
||||
instr = {}
|
||||
|
||||
while True:
|
||||
instr[ip] = []
|
||||
|
||||
fp = f.read(4)
|
||||
if len(fp) < 4: break
|
||||
|
||||
cmd = int.from_bytes(fp, "little", signed=True)
|
||||
if cmd == -1:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long 0x{data:08x}")
|
||||
#print(f"{cmd} (WRITE): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -9:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %byte 0x{data:02x}")
|
||||
#print(f"{cmd} (WRITE8): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -8:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word 0x{data:04x}")
|
||||
#print(f"{cmd} (WRITE16): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -2:
|
||||
offset = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"&var_a=data.long(0x{offset:08x})")
|
||||
#print(f"{cmd} (READ): {hex(offset)}")
|
||||
|
||||
elif cmd in [-3, -21]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
if cmd == -3:
|
||||
instr[ip].append(f"&and_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&and_b=&and_a | (0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and_b")
|
||||
|
||||
elif cmd == -21:
|
||||
instr[ip].append(f"&and_a=data.word(0x{offset:08x})")
|
||||
instr[ip].append(f"&and_b=&and_a | (0x{data:04x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word &and_b")
|
||||
|
||||
#print(f"{cmd} (AND): v({hex(offset)}) | {hex(data)}")
|
||||
|
||||
elif cmd in [-42, -44]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
if cmd == -42:
|
||||
instr[ip].append(f"&or_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &or_b")
|
||||
|
||||
elif cmd == -44:
|
||||
instr[ip].append(f"&or_a=data.word(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{data:04x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word &or_b")
|
||||
#print(f"{cmd} (OR): v({hex(offset)}) & ~{hex(data)}")
|
||||
|
||||
elif cmd == -43:
|
||||
offset, mask, data = struct.unpack("<LLL", f.read(12))
|
||||
instr[ip].append(f"&or_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{mask:08x})")
|
||||
|
||||
instr[ip].append(f"&and=&or_b | (0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and")
|
||||
#print(f"{cmd} (READ OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(data)}")
|
||||
|
||||
elif cmd == -250: # Unknown 2
|
||||
arg = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"¶m=0x{arg:08x}")
|
||||
#instr[ip].append(f"// {cmd}: {f.read(4)}")
|
||||
|
||||
elif cmd == -19:
|
||||
pos = int.from_bytes(f.read(4), "little", signed=True) + 1
|
||||
instr[ip].append(f"goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (SKIP), {pos}")
|
||||
|
||||
elif cmd == -40:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"&prn_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"print &prn_a")
|
||||
#print(f"{cmd} (READ_AND_PRINT), {hex(code)}")
|
||||
|
||||
elif cmd == -12: # COPROC
|
||||
cr_m, cr_n, cp_no, op, data = struct.unpack("<BBBBL", f.read(8))
|
||||
instr[ip].append(f"data.set c{cp_no}:0x{cr_n:04x} %long 0x{data:08x}")
|
||||
#print(F"{cmd} (COPROC) {cp_no}, {cr_n}, {cr_m}, {op}, {hex(data)}")
|
||||
|
||||
|
||||
elif cmd == -7: # Write again
|
||||
offset, value, mask = struct.unpack("<LLL", f.read(0xc))
|
||||
instr[ip].append(f"&and_a=(0x{mask:08x}) | (0x{value:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and_a")
|
||||
|
||||
#print(f"{cmd} (WRITE AND): {hex(offset)}, ({hex(mask)} | {hex(value)}) = {hex(value | mask)}")
|
||||
#print(f"{cmd} (WRITE OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(value)}")
|
||||
|
||||
elif cmd in [-17, -25]:
|
||||
offset, mask, expected, delay, pos = struct.unpack("<LLLLl", f.read(0x14))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"&assert_i = 0")
|
||||
instr[ip].append(f"while &assert_i < {delay + 1}")
|
||||
instr[ip].append("{")
|
||||
if cmd == -17:
|
||||
instr[ip].append(f" &assert_c = data.long(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}_true")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
elif cmd == -25:
|
||||
instr[ip].append(f" &assert_c = data.word(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:04x}) == 0x{expected:04x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}_true")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
instr[ip].append("}")
|
||||
instr[ip].append(f"goto has_{ip+pos}")
|
||||
instr[ip].append(f"has_{ip+pos}_true:")
|
||||
#print(f"{cmd} (READ and WAIT COND): ({hex(offset)} & {hex(mask)}) != {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd in [-18, -26]:
|
||||
offset, mask, expected, delay, pos = struct.unpack("<LLLLl", f.read(0x14))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"&assert_i = 0")
|
||||
instr[ip].append(f"while &assert_i < {delay + 1}")
|
||||
instr[ip].append("{")
|
||||
if cmd == -18:
|
||||
instr[ip].append(f" &assert_c = data.long(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
elif cmd == -26:
|
||||
instr[ip].append(f" &assert_c = data.word(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:04x}) == 0x{expected:04x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
instr[ip].append("}")
|
||||
#print(f"{cmd} (READ and WAIT COND): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -54:
|
||||
offset, bits = struct.unpack("<LL", f.read(0x8))
|
||||
instr[ip].append(f"// {cmd} (READ BYTES and PRINT) {hex(offset)} {bits}")
|
||||
|
||||
elif cmd == -59:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE8) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -58:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE16) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -41:
|
||||
reg = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f'print "0x{reg:02x}"')
|
||||
#print(f"{cmd} (PRINT): {hex(reg)}")
|
||||
|
||||
elif cmd == -38:
|
||||
mask, cond, pos = struct.unpack("<LLl", f.read(0xc))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"if (&var_a & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -39:
|
||||
mask, cond, pos = struct.unpack("<LLl", f.read(0xc))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"if (&var_a & 0x{mask:08x}) != 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (COND): (a & {hex(mask)}) != {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -255:
|
||||
instr[ip].append("end")
|
||||
#print(f"{cmd} (RETURN)")
|
||||
|
||||
elif cmd == -16:
|
||||
instr[ip].append(f"// {cmd}: {f.read(4)}")
|
||||
|
||||
elif cmd == -65536:
|
||||
instr[ip].append(f"// {cmd}: {f.read(8)}")
|
||||
|
||||
else:
|
||||
raise Exception(f"command {cmd} {hex(f.tell() - 4)}")
|
||||
|
||||
ip += 1
|
||||
|
||||
ip = 0
|
||||
while ip in instr:
|
||||
if ip in labels: print(f"{labels[ip]}:")
|
||||
for r in instr[ip]:
|
||||
print(r)
|
||||
import struct
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
|
||||
ip = 0
|
||||
labels = {}
|
||||
instr = {}
|
||||
|
||||
while True:
|
||||
instr[ip] = []
|
||||
|
||||
fp = f.read(4)
|
||||
if len(fp) < 4: break
|
||||
|
||||
cmd = int.from_bytes(fp, "little", signed=True)
|
||||
if cmd == -1:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long 0x{data:08x}")
|
||||
#print(f"{cmd} (WRITE): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -9:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %byte 0x{data:02x}")
|
||||
#print(f"{cmd} (WRITE8): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -8:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word 0x{data:04x}")
|
||||
#print(f"{cmd} (WRITE16): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -2:
|
||||
offset = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"&var_a=data.long(0x{offset:08x})")
|
||||
#print(f"{cmd} (READ): {hex(offset)}")
|
||||
|
||||
elif cmd in [-3, -21]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
if cmd == -3:
|
||||
instr[ip].append(f"&and_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&and_b=&and_a | (0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and_b")
|
||||
|
||||
elif cmd == -21:
|
||||
instr[ip].append(f"&and_a=data.word(0x{offset:08x})")
|
||||
instr[ip].append(f"&and_b=&and_a | (0x{data:04x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word &and_b")
|
||||
|
||||
#print(f"{cmd} (AND): v({hex(offset)}) | {hex(data)}")
|
||||
|
||||
elif cmd in [-42, -44]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
if cmd == -42:
|
||||
instr[ip].append(f"&or_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &or_b")
|
||||
|
||||
elif cmd == -44:
|
||||
instr[ip].append(f"&or_a=data.word(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{data:04x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %word &or_b")
|
||||
#print(f"{cmd} (OR): v({hex(offset)}) & ~{hex(data)}")
|
||||
|
||||
elif cmd == -43:
|
||||
offset, mask, data = struct.unpack("<LLL", f.read(12))
|
||||
instr[ip].append(f"&or_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"&or_b=&or_a & (~0x{mask:08x})")
|
||||
|
||||
instr[ip].append(f"&and=&or_b | (0x{data:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and")
|
||||
#print(f"{cmd} (READ OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(data)}")
|
||||
|
||||
elif cmd == -250: # Unknown 2
|
||||
arg = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"¶m=0x{arg:08x}")
|
||||
#instr[ip].append(f"// {cmd}: {f.read(4)}")
|
||||
|
||||
elif cmd == -19:
|
||||
pos = int.from_bytes(f.read(4), "little", signed=True) + 1
|
||||
instr[ip].append(f"goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (SKIP), {pos}")
|
||||
|
||||
elif cmd == -40:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f"&prn_a=data.long(0x{offset:08x})")
|
||||
instr[ip].append(f"print &prn_a")
|
||||
#print(f"{cmd} (READ_AND_PRINT), {hex(code)}")
|
||||
|
||||
elif cmd == -12: # COPROC
|
||||
cr_m, cr_n, cp_no, op, data = struct.unpack("<BBBBL", f.read(8))
|
||||
instr[ip].append(f"data.set c{cp_no}:0x{cr_n:04x} %long 0x{data:08x}")
|
||||
#print(F"{cmd} (COPROC) {cp_no}, {cr_n}, {cr_m}, {op}, {hex(data)}")
|
||||
|
||||
|
||||
elif cmd == -7: # Write again
|
||||
offset, value, mask = struct.unpack("<LLL", f.read(0xc))
|
||||
instr[ip].append(f"&and_a=(0x{mask:08x}) | (0x{value:08x})")
|
||||
instr[ip].append(f"data.set 0x{offset:08x} %long &and_a")
|
||||
|
||||
#print(f"{cmd} (WRITE AND): {hex(offset)}, ({hex(mask)} | {hex(value)}) = {hex(value | mask)}")
|
||||
#print(f"{cmd} (WRITE OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(value)}")
|
||||
|
||||
elif cmd in [-17, -25]:
|
||||
offset, mask, expected, delay, pos = struct.unpack("<LLLLl", f.read(0x14))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"&assert_i = 0")
|
||||
instr[ip].append(f"while &assert_i < {delay + 1}")
|
||||
instr[ip].append("{")
|
||||
if cmd == -17:
|
||||
instr[ip].append(f" &assert_c = data.long(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}_true")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
elif cmd == -25:
|
||||
instr[ip].append(f" &assert_c = data.word(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:04x}) == 0x{expected:04x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}_true")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
instr[ip].append("}")
|
||||
instr[ip].append(f"goto has_{ip+pos}")
|
||||
instr[ip].append(f"has_{ip+pos}_true:")
|
||||
#print(f"{cmd} (READ and WAIT COND): ({hex(offset)} & {hex(mask)}) != {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd in [-18, -26]:
|
||||
offset, mask, expected, delay, pos = struct.unpack("<LLLLl", f.read(0x14))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"&assert_i = 0")
|
||||
instr[ip].append(f"while &assert_i < {delay + 1}")
|
||||
instr[ip].append("{")
|
||||
if cmd == -18:
|
||||
instr[ip].append(f" &assert_c = data.long(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
elif cmd == -26:
|
||||
instr[ip].append(f" &assert_c = data.word(0x{offset:08x})")
|
||||
instr[ip].append(f" if (&assert_c & 0x{mask:04x}) == 0x{expected:04x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
instr[ip].append(f" &assert_i = &assert_i + 1")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
|
||||
instr[ip].append("}")
|
||||
#print(f"{cmd} (READ and WAIT COND): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -54:
|
||||
offset, bits = struct.unpack("<LL", f.read(0x8))
|
||||
instr[ip].append(f"// {cmd} (READ BYTES and PRINT) {hex(offset)} {bits}")
|
||||
|
||||
elif cmd == -59:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE8) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -58:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE16) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -41:
|
||||
reg = int.from_bytes(f.read(4), "little")
|
||||
instr[ip].append(f'print "0x{reg:02x}"')
|
||||
#print(f"{cmd} (PRINT): {hex(reg)}")
|
||||
|
||||
elif cmd == -38:
|
||||
mask, cond, pos = struct.unpack("<LLl", f.read(0xc))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"if (&var_a & 0x{mask:08x}) == 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -39:
|
||||
mask, cond, pos = struct.unpack("<LLl", f.read(0xc))
|
||||
pos += 1
|
||||
|
||||
instr[ip].append(f"if (&var_a & 0x{mask:08x}) != 0x{expected:08x}")
|
||||
instr[ip].append(f" goto has_{ip+pos}")
|
||||
labels[ip+pos] = f"has_{ip+pos}"
|
||||
#print(f"{cmd} (COND): (a & {hex(mask)}) != {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -255:
|
||||
instr[ip].append("end")
|
||||
#print(f"{cmd} (RETURN)")
|
||||
|
||||
elif cmd == -16:
|
||||
instr[ip].append(f"// {cmd}: {f.read(4)}")
|
||||
|
||||
elif cmd == -65536:
|
||||
instr[ip].append(f"// {cmd}: {f.read(8)}")
|
||||
|
||||
else:
|
||||
raise Exception(f"command {cmd} {hex(f.tell() - 4)}")
|
||||
|
||||
ip += 1
|
||||
|
||||
ip = 0
|
||||
while ip in instr:
|
||||
if ip in labels: print(f"{labels[ip]}:")
|
||||
for r in instr[ip]:
|
||||
print(r)
|
||||
ip += 1
|
||||
|
|
@ -1,97 +1,97 @@
|
|||
import struct
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
|
||||
while True:
|
||||
fp = f.read(4)
|
||||
if len(fp) < 4: break
|
||||
|
||||
cmd = int.from_bytes(fp, "little", signed=True)
|
||||
if cmd == -1:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -9:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE8): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -8:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE16): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -2:
|
||||
offset = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (READ): {hex(offset)}")
|
||||
|
||||
elif cmd in [-3, -21]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (AND): v({hex(offset)}) | {hex(data)}")
|
||||
|
||||
elif cmd in [-42, -44]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (OR): v({hex(offset)}) & ~{hex(data)}")
|
||||
|
||||
elif cmd == -43:
|
||||
offset, mask, data = struct.unpack("<LLL", f.read(12))
|
||||
print(f"{cmd} (READ OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(data)}")
|
||||
|
||||
elif cmd == -250:
|
||||
arg = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd}: (SET ARGS) {arg}")
|
||||
|
||||
elif cmd == -19:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (SKIP), {code}")
|
||||
|
||||
elif cmd == -40:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (READ_AND_PRINT), {hex(code)}")
|
||||
|
||||
elif cmd == -12: # COPROC
|
||||
cr_m, cr_n, cp_no, op, data = struct.unpack("<BBBBL", f.read(8))
|
||||
print(F"{cmd} (COPROC) {cp_no}, {cr_n}, {cr_m}, {op}, {hex(data)}")
|
||||
|
||||
elif cmd == -7: # Write again
|
||||
offset, value, mask = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE AND): {hex(offset)}, ({hex(mask)} | {hex(value)}) = {hex(value | mask)}")
|
||||
#print(f"{cmd} (WRITE OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(value)}")
|
||||
|
||||
elif cmd in [-17, -25]:
|
||||
offset, mask, expected, delay, branch = struct.unpack("<LLLLL", f.read(0x14))
|
||||
print(f"{cmd} (POLL_TIMEOUT): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TIMEOUT")
|
||||
|
||||
elif cmd in [-18, -26]:
|
||||
offset, mask, expected, delay, branch = struct.unpack("<LLLLL", f.read(0x14))
|
||||
print(f"{cmd} (POLL): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -54:
|
||||
offset, bits = struct.unpack("<LL", f.read(0x8))
|
||||
print(f"{cmd} (READ BYTES and PRINT) {hex(offset)} {bits}")
|
||||
|
||||
elif cmd == -59:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE8) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -58:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE16) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -41:
|
||||
reg = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (PRINT): {hex(reg)}")
|
||||
|
||||
elif cmd == -38:
|
||||
mask, cond, branch = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -39:
|
||||
mask, cond, branch = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if FALSE")
|
||||
|
||||
elif cmd == -255:
|
||||
print(f"{cmd} (RETURN)")
|
||||
|
||||
else:
|
||||
import struct
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
|
||||
while True:
|
||||
fp = f.read(4)
|
||||
if len(fp) < 4: break
|
||||
|
||||
cmd = int.from_bytes(fp, "little", signed=True)
|
||||
if cmd == -1:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -9:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE8): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -8:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (WRITE16): {hex(offset)} {hex(data)}")
|
||||
|
||||
elif cmd == -2:
|
||||
offset = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (READ): {hex(offset)}")
|
||||
|
||||
elif cmd in [-3, -21]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (AND): v({hex(offset)}) | {hex(data)}")
|
||||
|
||||
elif cmd in [-42, -44]:
|
||||
offset, data = struct.unpack("<LL", f.read(8))
|
||||
print(f"{cmd} (OR): v({hex(offset)}) & ~{hex(data)}")
|
||||
|
||||
elif cmd == -43:
|
||||
offset, mask, data = struct.unpack("<LLL", f.read(12))
|
||||
print(f"{cmd} (READ OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(data)}")
|
||||
|
||||
elif cmd == -250:
|
||||
arg = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd}: (SET ARGS) {arg}")
|
||||
|
||||
elif cmd == -19:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (SKIP), {code}")
|
||||
|
||||
elif cmd == -40:
|
||||
code = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (READ_AND_PRINT), {hex(code)}")
|
||||
|
||||
elif cmd == -12: # COPROC
|
||||
cr_m, cr_n, cp_no, op, data = struct.unpack("<BBBBL", f.read(8))
|
||||
print(F"{cmd} (COPROC) {cp_no}, {cr_n}, {cr_m}, {op}, {hex(data)}")
|
||||
|
||||
elif cmd == -7: # Write again
|
||||
offset, value, mask = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE AND): {hex(offset)}, ({hex(mask)} | {hex(value)}) = {hex(value | mask)}")
|
||||
#print(f"{cmd} (WRITE OR): (v({hex(offset)}) & ~{hex(mask)}) | {hex(value)}")
|
||||
|
||||
elif cmd in [-17, -25]:
|
||||
offset, mask, expected, delay, branch = struct.unpack("<LLLLL", f.read(0x14))
|
||||
print(f"{cmd} (POLL_TIMEOUT): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TIMEOUT")
|
||||
|
||||
elif cmd in [-18, -26]:
|
||||
offset, mask, expected, delay, branch = struct.unpack("<LLLLL", f.read(0x14))
|
||||
print(f"{cmd} (POLL): ({hex(offset)} & {hex(mask)}) == {expected}, max: {delay}ms, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -54:
|
||||
offset, bits = struct.unpack("<LL", f.read(0x8))
|
||||
print(f"{cmd} (READ BYTES and PRINT) {hex(offset)} {bits}")
|
||||
|
||||
elif cmd == -59:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE8) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -58:
|
||||
offset, count, value = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (WRITE16) {hex(offset)} {hex(value)} {count}")
|
||||
|
||||
elif cmd == -41:
|
||||
reg = int.from_bytes(f.read(4), "little")
|
||||
print(f"{cmd} (PRINT): {hex(reg)}")
|
||||
|
||||
elif cmd == -38:
|
||||
mask, cond, branch = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if TRUE")
|
||||
|
||||
elif cmd == -39:
|
||||
mask, cond, branch = struct.unpack("<LLL", f.read(0xc))
|
||||
print(f"{cmd} (COND): (a & {hex(mask)}) == {hex(cond)}, SKIP {branch} INSTRUCTION if FALSE")
|
||||
|
||||
elif cmd == -255:
|
||||
print(f"{cmd} (RETURN)")
|
||||
|
||||
else:
|
||||
raise Exception(f"command {cmd} {hex(f.tell() - 4)}")
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
fo = open(sys.argv[2], "wb")
|
||||
|
||||
while True:
|
||||
flag = f.read(2)
|
||||
if len(flag) == 0: break
|
||||
|
||||
flag = int.from_bytes(flag, "little")
|
||||
|
||||
count = flag & 0x7fff
|
||||
rle = flag >> 15
|
||||
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = open(sys.argv[1], "rb")
|
||||
fo = open(sys.argv[2], "wb")
|
||||
|
||||
while True:
|
||||
flag = f.read(2)
|
||||
if len(flag) == 0: break
|
||||
|
||||
flag = int.from_bytes(flag, "little")
|
||||
|
||||
count = flag & 0x7fff
|
||||
rle = flag >> 15
|
||||
|
||||
fo.write((f.read(1) * count) if rle else f.read(count))
|
||||
Loading…
Add table
Add a link
Reference in a new issue