reboot part 1

This commit is contained in:
wrapper 2026-03-22 11:47:18 +07:00
parent c762dc9e25
commit 980f754843
237 changed files with 2574 additions and 2119 deletions

5
.gitignore vendored
View file

@ -14,4 +14,7 @@ compress_test.bat
build/
dcc_test_*
build_script/
test_emu/
test_emu/
*.pyc
dcc_test.py
old_stuff/

View file

@ -66,7 +66,6 @@
"C_Cpp_Runner.msvcSecureNoWarnings": false,
"clangd.fallbackFlags": [
"-I${workspaceRoot}",
"-DDCC_TESTING=1",
"-DDCC_BUFFER_SIZE=0x40000"
]
}

86
crt.s
View file

@ -14,17 +14,17 @@
/*
* 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
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 */
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 */
@ -47,12 +47,12 @@ _vectors:
.global ResetHandler
.global ExitFunction
.extern pic_relocate
.global DN_Packet_DCC_WaitForBP
#if USE_BREAKPOINTS
.global DN_Packet_DCC_WaitForBP
.global DCC_PKT_RW_DATA
.global DCC_PKT_RW_SIZE
#endif
.extern pic_relocate
.extern dcc_main
.extern __stack_und_end
@ -60,12 +60,14 @@ _vectors:
StartAddress: .word 0xffffffff
FlashSize: .word 0x0
PageSize: .word 0xffffffff
/* Loader via H/W BP polling */
DCC_PKT_RW_SIZE: .word 0xffffffff
DCC_PKT_RW_DATA: .word 0xffffffff
DCC_PKT_HW_BP: .word DN_Packet_DCC_WaitForBP
DCC_CANWRITE: .word 0x0
/* Crash handlers */
UndefHandler:
SWIHandler:
PAbortHandler:
@ -76,21 +78,14 @@ CrashHandler:
b CrashHandler
.word CrashHandler
/* DCC info */
.word __heap_start
.word __heap_end
.word __heap_size
.word __stack_end
.asciz "A:DumpNow DCC Loader. (c) 2026 Wrapper.;Compile flags: " ADEFS ";Compile Date: " __DATE__
.align
/* LWMEM info */
#if HAVE_LWMEM
lwmem_init:
.word __heap_start
.word __heap_size
lwmem_init_end:
.word 0x00000000
.word 0x00000000
#endif
/****************************************************************************/
/* Reset handler */
/****************************************************************************/
@ -110,7 +105,7 @@ ResetHandler:
mcr p15, 0, r0, cr1, cr0, 0
#endif
/* TODO: Why is this line necessary */
/* Needed to flush DCC read buffer */
#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__) )
@ -121,6 +116,7 @@ ResetHandler:
mrc p14, 0, r0, cr1, cr0, 0
#endif
/* 01 - Initialize stack section */
mov r0, #0
adr r0, _vectors
@ -129,6 +125,7 @@ ResetHandler:
bl plat_init
/* 02 - Reset memory */
mov r0, #0
adr r0, _vectors
@ -146,7 +143,6 @@ bss_clear_loop:
strne r3, [r1], #+4
bne bss_clear_loop
#if HAVE_LWMEM
/*
* Clear .heap section
*/
@ -159,46 +155,16 @@ heap_clear_loop:
cmp r1, r2
strne r3, [r1], #+4
bne heap_clear_loop
#endif
/*
* Jump to main
*/
#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
*/
/* Setup PIC */
/* 03 - Code initialize */
mov r0, #0
adr r0, _vectors
/* Setup PIC */
ldr r1, =_reloc_start
add r1, r0
ldr r2, =_reloc_end
add r1, r0
add r2, r0
ldr r3, =edata
@ -209,7 +175,7 @@ heap_clear_loop:
ldr r9, =_sgot
add r9, r0
/* Jump to Main */
/* 04 - Jump to Main */
mov r0, #0
adr r0, StartAddress
ldr r0, [r0]

View file

@ -1,4 +1,4 @@
#include "dcc/plat.h"
#include "plat.h"
#include "bitutils.h"
/*

View file

@ -2,7 +2,7 @@
#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);
#define BIT_SET_VAR(src, bm, value) (src) = BIT_SET(src, bm, value)
typedef struct {
uint32_t bit_pos;

View file

@ -92,7 +92,6 @@ void DN_RLE_FindMatch(uint8_t *src, uint32_t *RAW_Count, uint32_t *RLE_Count, ui
uint32_t runCount = 1;
uint32_t pReadSize = size < 0x7fff ? size : 0x7fff;
uint32_t rawCount = 0;
while (pReadOffset < (pReadSize - 1)) {
wdog_reset();
@ -259,24 +258,13 @@ 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 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;
@ -331,6 +319,7 @@ uint32_t DN_Packet_DCC_Read(void) {
#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;
@ -394,6 +383,32 @@ void DN_Packet_Send_One(uint32_t data) {
#endif
}
void DN_Packet_Send_DirectUncompressed(uint8_t *src, uint32_t size) {
if (size & 3) return; // Must be dword aligned
uint32_t MAGIC = CMD_WRITE_COMP_NONE;
uint32_t checksum = DN_Calculate_CRC32(0xffffffff, (uint8_t *)&MAGIC, 4);
checksum = DN_Calculate_CRC32(checksum, src, size);
#if USE_BREAKPOINTS
DN_Packet_DCC_ResetBPP(cmdBuf);
#endif
DN_Packet_DCC_Send((size >> 2) + 1);
DN_Packet_DCC_Send(CMD_WRITE_COMP_NONE);
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_Read(uint8_t *dest, uint32_t size) {
if (size & 3) return; // Must be dword aligned
@ -404,6 +419,61 @@ void DN_Packet_Read(uint8_t *dest, uint32_t size) {
}
/* 04 - DCC Buffer */
static uint32_t dcc_temp_read;
static uint8_t dcc_buf_offset;
void DN_Packet_DCC_Read_Buffer_Reset(void) {
dcc_temp_read = 0;
dcc_buf_offset = 0;
}
static inline uint8_t DN_Packet_DCC_Read_Buffer8(void) {
if (!dcc_buf_offset) dcc_temp_read = DN_Packet_DCC_Read();
uint8_t temp = dcc_temp_read & 0xff;
dcc_temp_read >>= 8;
dcc_buf_offset = (dcc_buf_offset + 1) & 3;
return temp;
}
static inline uint16_t DN_Packet_DCC_Read_Buffer16(void) {
return DN_Packet_DCC_Read_Buffer8() | DN_Packet_DCC_Read_Buffer8() << 8;
}
static inline uint32_t DN_Packet_DCC_Read_Buffer32(void) {
return DN_Packet_DCC_Read_Buffer16() | DN_Packet_DCC_Read_Buffer16() << 16;
}
void DN_Packet_DCC_ReadCompressed(uint8_t *dest, uint32_t size) {
uint32_t inOffset = 0;
uint32_t outOffset = 0;
DN_Packet_DCC_Read_Buffer_Reset();
while (inOffset < size) {
uint16_t flag = DN_Packet_DCC_Read_Buffer16();
uint16_t count = flag & 0x7fff;
if (flag & 0x8000) {
inOffset += 3;
uint8_t data = DN_Packet_DCC_Read_Buffer8();
memset(dest + outOffset, data, count);
outOffset += count;
// do {
// dest[outOffset++] = data;
// } while (count--);
} else {
inOffset += 2 + count;
do {
dest[outOffset++] = DN_Packet_DCC_Read_Buffer8();
} while (--count);
}
}
}
#if 0
static uint32_t temp_buf;
static uint8_t temp_buf_offset;
static uint32_t checksum;
@ -634,33 +704,7 @@ static inline uint16_t DN_Packet_DCC_Read_Buffer16(void) {
static inline uint32_t DN_Packet_DCC_Read_Buffer32(void) {
return DN_Packet_DCC_Read_Buffer16() | DN_Packet_DCC_Read_Buffer16() << 16;
}
void DN_Packet_DCC_ReadCompressed(uint8_t *dest, uint32_t size) {
uint32_t inOffset = 0;
uint32_t outOffset = 0;
DN_Packet_DCC_Read_Buffer_Reset();
while (inOffset < size) {
uint16_t flag = DN_Packet_DCC_Read_Buffer16();
uint16_t count = flag & 0x7fff;
if (flag & 0x8000) {
inOffset += 3;
uint8_t data = DN_Packet_DCC_Read_Buffer8();
do {
dest[outOffset++] = data;
} while (count--);
} else {
inOffset += 2 + count;
do {
dest[outOffset++] = DN_Packet_DCC_Read_Buffer8();
} while (count--);
}
}
}
#endif
/* 05 - Utilities */
uint32_t DN_Log2(uint32_t value)

View file

@ -35,7 +35,7 @@ typedef enum {
} Configuration;
typedef struct {
DCC_RETURN (*initialize)(DCCMemory *mem, uint32_t offset);
DCC_RETURN (*initialize)(DCCMemory *mem, uint32_t offset, uint32_t page_size);
DCC_RETURN (*read)(DCCMemory *mem, uint32_t offset, uint32_t size, uint8_t *dest, uint32_t *dest_size);
DCC_RETURN (*write)(DCCMemory *mem, uint32_t offset, uint8_t *src, uint32_t size);
DCC_RETURN (*erase)(DCCMemory *mem, uint32_t offset, uint32_t size);
@ -123,8 +123,10 @@ typedef struct {
#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
#define DCC_E_INSUFF_DATA 0x3E // Insufficient data
// Functions
// 01 - Compress
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);
@ -132,18 +134,31 @@ uint32_t DN_Packet_Compress2(uint8_t *src, uint32_t size, uint8_t *dest);
#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);
// 02 - DCC main routines
uint32_t DN_Packet_DCC_Send(uint32_t data);
uint32_t DN_Packet_DCC_Read(void);
// 03 - DCC Write routines
void DN_Packet_Send(uint8_t *src, uint32_t size);
void DN_Packet_Send_One(uint32_t data);
void DN_Packet_Send_DirectUncompressed(uint8_t *src, uint32_t size);
// 04 - DCC Read routines
void DN_Packet_Read(uint8_t *dest, uint32_t size);
void DN_Packet_DCC_ReadCompressed(uint8_t *dest, uint32_t size);
uint32_t DN_Calculate_CRC32(uint32_t crc, uint8_t* data, uint32_t len);
// 05 - Utilities
uint32_t DN_Log2(uint32_t value);
void DN_WaitUSec(uint32_t usec);
void DN_Packet_WriteDirectCompressed(uint8_t *src, uint32_t size);
void DN_Packet_WriteDirect(uint8_t *src, uint32_t size);
void DN_Packet_DCC_ReadCompressed(uint8_t *dest, uint32_t size);
// 06 - Unused
// void DN_Packet_WriteDirectCompressed(uint8_t *src, uint32_t size);
// void DN_Packet_WriteDirect(uint8_t *src, uint32_t size);
// void DN_Packet_DCC_ReadCompressed(uint8_t *dest, uint32_t size);
// Watchdog
extern void wdog_reset(void);
extern void wdog_reset(void);
// GPIO
extern uint8_t plat_gpio_read(uint32_t pin);
extern void plat_gpio_write(uint32_t pin, uint8_t active);
extern void plat_gpio_set_dir(uint32_t pin, GPIODirection dir);
extern void plat_gpio_set_alt_func(uint32_t pin, uint32_t alt_func);
extern void plat_gpio_set_pull(uint32_t pin, GPIOPullType pull);

View file

@ -5,10 +5,10 @@ typedef struct {
uint32_t type;
} RELOC;
void pic_relocate(uint32_t base, uint32_t reloc_cur, uint32_t reloc_end, uint32_t data_offs) {
void pic_relocate(uint32_t base, RELOC *reloc_cur, RELOC *reloc_end, uint32_t data_end_offset) {
while (reloc_cur < reloc_end) {
RELOC *rel = (RELOC *)(reloc_cur);
if (rel->type == 0x17 && rel->offset >= data_offs) *((uint32_t *)(base + rel->offset)) += base;
reloc_cur += sizeof(RELOC);
RELOC *rel = reloc_cur++;
if (rel->type == 0x17 && rel->offset >= data_end_offset)
*((uint32_t *)(base + rel->offset)) += base;
}
}

View file

@ -2,6 +2,18 @@
#include <stdint.h>
#include <stddef.h>
#include <memory.h>
#include "bitutils.h"
typedef enum {
GPIO_INPUT,
GPIO_OUTPUT
} GPIODirection;
typedef enum {
GPIO_PULL_DISABLED,
GPIO_PULL_UP,
GPIO_PULL_DOWN
} GPIOPullType;
#ifdef DCC_TESTING
#include <stdio.h>
@ -18,7 +30,9 @@ extern void *PLAT_MEMCPY(void *dest, const void *src, size_t n);
#define INT_MEMCPY memcpy
#define PLAT_SNPRINTF snprintf
#else
#include "dcc/lwprintf.h"
#include "lwprintf.h"
#define SET_BIT_BM_BP(val, bit_mask, bit_pos) (val) = ((val) & ~((bit_mask) << (bit_pos))) | (((val) & (bit_mask)) << (bit_pos))
#define WRITE_U8(_reg, _val) (*((volatile uint8_t *)(_reg)) = (_val))
#define WRITE_U16(_reg, _val) (*((volatile uint16_t *)(_reg)) = (_val))

View file

@ -0,0 +1,8 @@
#include "dcc/dn_dcc_proto.h"
#include "flash/onenand/onenand.h"
Device devices[] = {
{&onenand_controller, 0x38000000},
// {&nand_controller, 0x0},
{0x0, 0x0}
};

View file

@ -51,7 +51,7 @@ DCC_RETURN CFI_Query(uint32_t offset, uint32_t type, CFIQuery *qry) {
return DCC_OK;
}
DCC_RETURN CFI_Probe(DCCMemory *mem, uint32_t offset) {
DCC_RETURN CFI_Probe(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
uint32_t CFI_Type;
CFIQuery qry = { 0 };
DCC_RETURN ret_code;

View file

@ -3,7 +3,7 @@
#include "mmap.h"
#include "dcc/dn_dcc_proto.h"
DCC_RETURN Memdump_Probe(DCCMemory *mem, uint32_t offset) {
DCC_RETURN Memdump_Probe(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
mem->manufacturer = MEMDUMP_MFR;
mem->device_id = MEMDUMP_DEVID;
mem->bit_width = 16;

View file

@ -0,0 +1,182 @@
/* Nand controller template */
#include "../controller.h"
#include "dcc/dn_dcc_proto.h"
#include "dcc/plat.h"
static uint8_t bits;
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
// Write command routines
WRITE_U8(0x80010000, cmd);
wdog_reset();
}
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
// Write address routines
WRITE_U8(0x80020000, addr);
wdog_reset();
}
uint16_t inline NAND_Ctrl_Data_Read() {
// Data read routines
wdog_reset();
return bits == 16 ? READ_U16(0x80000000) : READ_U8(0x80000000); // TODO: 32-bit NAND data read
}
void inline NAND_Ctrl_Wait_Ready() {
// Busy assert routines
do { wdog_reset(); } while (READ_U32(0x9F8000C8) & 2) ;
}
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_Wait_Ready();
NAND_Ctrl_Command_Write(NAND_CMD_READID);
NAND_Ctrl_Address_Write(0x0);
NAND_Ctrl_Wait_Ready();
uint8_t mfr_id = (uint8_t)NAND_Ctrl_Data_Read();
uint8_t dev_id = (uint8_t)NAND_Ctrl_Data_Read();
for (int i = 0; flash_ids[i].dev_id; i++) {
if (dev_id == (uint8_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;
}
bits = mem->bit_width;
NAND_Ctrl_Command_Write(NAND_CMD_RESET);
NAND_Ctrl_Wait_Ready();
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

@ -2,5 +2,6 @@
#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)
// for NAND, EBI2_CS1_N is always connected and NAND_BUS_ENA is set (by default, this is on)
#include "msm7200.c"

View file

@ -0,0 +1,180 @@
/* Nand controller template */
#include "../controller.h"
#include "dcc/plat.h"
#define NAND_BASE 0x40000000
static uint8_t counter;
void inline NAND_Ctrl_Command_Write(uint8_t cmd) {
// Write command routines
WRITE_U8(NAND_BASE | 0x1000000, cmd);
wdog_reset();
}
void inline NAND_Ctrl_Address_Write(uint8_t addr) {
// Write address routines
WRITE_U8(NAND_BASE | ((counter++ >= 4) ? 0x9000000 : 0x800000), addr);
wdog_reset();
}
uint16_t inline NAND_Ctrl_Data_Read() {
// Data read routines
wdog_reset();
return READ_U8(NAND_BASE);
}
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_Wait_Ready();
NAND_Ctrl_Command_Write(NAND_CMD_READID);
NAND_Ctrl_Address_Write(0x0);
NAND_Ctrl_Wait_Ready();
uint8_t mfr_id = (uint8_t)NAND_Ctrl_Data_Read();
uint8_t dev_id = (uint8_t)NAND_Ctrl_Data_Read();
for (int i = 0; flash_ids[i].dev_id; i++) {
if (dev_id == (uint8_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);
NAND_Ctrl_Wait_Ready();
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

@ -60,7 +60,7 @@ const nand_info flash_ids[] = {
{0, 0, 0, 0, 0}
};
DCC_RETURN NAND_Probe(DCCMemory *mem, uint32_t offset) {
DCC_RETURN NAND_Probe(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
return NAND_Ctrl_Probe(mem);
}

View file

@ -61,7 +61,7 @@
// Single register R/W
int OneNAND_Ctrl_Wait_Ready(DCCMemory *mem, uint16_t flag);
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset);
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset, uint32_t page_size);
void OneNAND_Ctrl_Reg_Write(DCCMemory *mem, uint16_t reg, uint16_t data, uint8_t wait_interrupt);
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

@ -5,10 +5,14 @@
#include <stdint.h>
#include "dcc/dn_dcc_proto.h"
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
// Initialize routines
mem->base_offset = offset;
mem->page_size = 0x800;
if (page_size != 0x800 && page_size != 0x1000) {
page_size = 0x800;
}
mem->page_size = page_size;
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_SYS_CFG1, 0x40c0, 0);

View file

@ -48,10 +48,14 @@ int OneNAND_Ctrl_Wait_Ready(DCCMemory *mem, uint16_t flag) {
return 1;
}
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset) {
void OneNAND_Pre_Initialize(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
// Initialize routines
mem->base_offset = offset;
mem->page_size = 0x800;
if (page_size != 0x800 && page_size != 0x1000) {
page_size = 0x800;
}
mem->page_size = page_size;
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG0, 0xaad4001a);
WRITE_U32(REGS_START + MSM7200_REG_DEV0_CFG1, 0x2101bd);

View file

@ -2,9 +2,9 @@
#include "dcc/dn_dcc_proto.h"
#include "controller/controller.h"
uint32_t OneNAND_Probe(DCCMemory *mem, uint32_t offset) {
uint32_t OneNAND_Probe(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
wdog_reset();
OneNAND_Pre_Initialize(mem, offset);
OneNAND_Pre_Initialize(mem, offset, page_size);
if (!OneNAND_Ctrl_Wait_Ready(mem, 0x8000)) return DCC_PROBE_ERROR;
@ -28,9 +28,9 @@ uint32_t OneNAND_Read_Upper(DCCMemory *mem, uint8_t *page_buf, uint8_t *spare_bu
wdog_reset();
OneNAND_Ctrl_Reg_Write(mem, O1N_REG_ECC_STATUS, 0x0, 0);
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));
uint32_t density_n = 2 << (3 + ((mem->device_id >> 4) & 0xf));
uint32_t addr1_mask = ((mem->device_id & 8) ? (density_n << 2) : (density_n << 3)) - 1;
uint32_t ddp_access = (mem->device_id & 8) && ((page >> 6) >= (density_n << 2));
OneNAND_Ctrl_Reg_Write_Queue(mem, O1N_REG_START_ADDRESS8, (page & 63) << 2);
OneNAND_Ctrl_Reg_Write_Queue(mem, O1N_REG_START_ADDRESS1, (ddp_access ? 0x8000 : 0) | ((page >> 6) & addr1_mask));

View file

@ -22,7 +22,7 @@ const superand_info flash_ids[] = {
{0x5b, 0x200, 0x04000000, 0x4000, 16},
};
DCC_RETURN SuperAND_Probe(DCCMemory *mem, uint32_t offset) {
DCC_RETURN SuperAND_Probe(DCCMemory *mem, uint32_t offset, uint32_t page_size) {
return SuperAND_Ctrl_Probe(mem);
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more