Move to linux

This commit is contained in:
wrapper 2025-05-22 22:05:39 +07:00
parent 6d1b49ae02
commit ebe3b20f58
91 changed files with 23251 additions and 23149 deletions

26
.gitignore vendored
View file

@ -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
View 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
View 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
View file

@ -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}"
]
}

1348
LICENSE

File diff suppressed because it is too large Load diff

View file

@ -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
View file

@ -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 ***/

View file

@ -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);
}

View file

@ -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);

View file

@ -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++;
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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}
};

View file

@ -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
};

View file

@ -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;

View file

@ -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
};

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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"

View file

@ -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"

View file

@ -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;
}

View file

@ -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};

View file

@ -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"

View file

@ -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"

View file

@ -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;
}

View file

@ -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};

View file

@ -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;
}

View file

@ -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};

View file

@ -1,3 +1,3 @@
#define REGS_START 0x80008000
#define REGS_START 0x80008000
#include "msm7200.c"

View file

@ -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"

View file

@ -1,3 +1,3 @@
#define REGS_START 0x70000000
#define REGS_START 0x70000000
#include "msm7200.c"

View file

@ -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"

View file

@ -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;
}

View file

@ -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};

View file

@ -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"

View file

@ -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"

View file

@ -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
};

View file

@ -1,4 +1,4 @@
#pragma once
#include "dcc/dn_dcc_proto.h"
#pragma once
#include "dcc/dn_dcc_proto.h"
extern Driver nand_controller;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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};

View file

@ -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
};

View file

@ -1,4 +1,4 @@
#pragma once
#include "dcc/dn_dcc_proto.h"
#pragma once
#include "dcc/dn_dcc_proto.h"
extern Driver onenand_controller;

View file

@ -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);

View file

@ -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;
}

View file

@ -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
};

View file

@ -1,4 +1,4 @@
#pragma once
#include "dcc/dn_dcc_proto.h"
#pragma once
#include "dcc/dn_dcc_proto.h"
extern Driver superand_controller;

View file

@ -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
View file

@ -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));
}
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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)))

View file

@ -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)))

View file

@ -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)

View file

@ -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"&param=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"&param=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

View file

@ -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)}")

View file

@ -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))