diff --git a/crt.s b/crt.s index 1a82d7f..450c55d 100644 --- a/crt.s +++ b/crt.s @@ -47,20 +47,23 @@ _vectors: .global ResetHandler .global ExitFunction + #if USE_BREAKPOINTS .global DN_Packet_DCC_WaitForBP .global DCC_PKT_RW_DATA .global DCC_PKT_RW_SIZE #endif -#ifndef NO_PIC + +#ifdef PIC .extern pic_relocate #endif + .extern dcc_main .extern __stack_und_end /* Variables */ StartAddress: .word 0xffffffff -FlashSize: .word 0x0 +NoAutoSize: .word 0x0 PageSize: .word 0xffffffff /* Loader via H/W BP polling */ @@ -82,10 +85,10 @@ CrashHandler: /* DCC info */ .ascii "DNDL" -#ifdef NO_PIC -.word 0 -#else +#ifdef PIC .word 1 +#else +.word 0 #endif .word _vectors .word __bss_start @@ -124,20 +127,20 @@ ResetHandler: #endif /* 01 - Initialize stack section */ -#ifndef NO_PIC +#ifdef PIC mov r0, #0 adr r0, _vectors #endif ldr sp, =__stack_svc_end -#ifndef NO_PIC +#ifdef PIC add sp, r0 #endif bl plat_init /* 02 - Reset memory */ -#ifndef NO_PIC +#ifdef PIC mov r0, #0 adr r0, _vectors #endif @@ -149,7 +152,7 @@ ResetHandler: ldr r2, =__bss_end mov r3, #0 -#ifndef NO_PIC +#ifdef PIC add r1, r0 add r2, r0 #endif @@ -159,7 +162,7 @@ bss_clear_loop: bne bss_clear_loop /* 03 - Code initialize */ -#ifndef NO_PIC +#ifdef PIC mov r0, #0 adr r0, _vectors diff --git a/dcc/lwprintf_opts.h b/dcc/lwprintf_opts.h index 116a569..e16359a 100644 --- a/dcc/lwprintf_opts.h +++ b/dcc/lwprintf_opts.h @@ -40,6 +40,8 @@ * Open "include/lwprintf/lwprintf_opt.h" and * copy & replace here settings you want to change values */ + +#define LWPRINTF_CFG_SUPPORT_LONG_LONG 0 #define LWPRINTF_CFG_SUPPORT_TYPE_FLOAT 0 #define LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING 0 diff --git a/flash/nand/controller/emp/db2020.c b/flash/nand/controller/emp/db2020.c new file mode 100644 index 0000000..5bd70aa --- /dev/null +++ b/flash/nand/controller/emp/db2020.c @@ -0,0 +1,219 @@ +/* Nand controller template */ +#include "../controller.h" +#include "dcc/dn_dcc_proto.h" +#include "dcc/plat.h" +#include "./db2020.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(); +} + +void inline DB2xxx_NAND_ReadData(unsigned char *data) { + int count = 0x10; + uint32_t temp; + + do { + do { wdog_reset(); } while (!(READ_U32(NAND_CTRL_BASE + REG_INTERRUPT) & 4)); + + for (int i = 0; i < 8; i++) { + temp = READ_U32(NAND_CTRL_BASE + REG_DATA_READ); + *data = temp; + *(data + 1) = temp >> 8; + *(data + 2) = temp >> 0x10; + *(data + 3) = temp >> 0x18; + data += 4; + } + + WRITE_U32(NAND_CTRL_BASE + REG_INTERRUPT, 0xff); + count--; + } while (count); +} + +void inline DB2xxx_NAND_ReadOOB(unsigned char *oob) { + uint32_t temp; + + // do { wdog_reset(); } while (!(READ_U32(NAND_CTRL_BASE + REG_INTERRUPT) & 4)); + + for (int i = 0; i < 4; i++) { + temp = READ_U32(NAND_CTRL_BASE + REG_DATA_READ); + *oob = temp; + *(oob + 1) = temp >> 8; + *(oob + 2) = temp >> 0x10; + *(oob + 3) = temp >> 0x18; + oob += 4; + } +} + +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; +} \ No newline at end of file diff --git a/flash/nand/controller/emp/db2020.h b/flash/nand/controller/emp/db2020.h new file mode 100644 index 0000000..0c7b7c6 --- /dev/null +++ b/flash/nand/controller/emp/db2020.h @@ -0,0 +1,34 @@ +#pragma once + +#define NAND_CTRL_BASE 0x24000000 + +#define REG_DATA 0x04 +#define REG_ADDR 0x08 +#define REG_CFG 0x10 +#define REG_INTERRUPT 0x18 +#define REG_STATUS 0x1c +#define REG_CMD 0x20 +#define REG_CMD2 0x24 +#define REG_ALWAYS_ONE 0x50 +#define REG_DATA_READ 0x54 +#define REG_CTRL 0x58 +#define REG_ALWAYS_TWO_01 0x5c +#define REG_ALWAYS_TWO_02 0x8c +#define REG_ALWAYS_TWO_03 0x90 + +#define VAL_RUN_CFG 0x5603 +#define VAL_IDLE_CFG 0x5703 + +#define VAL_CMD_MASK 0xFFFF0000 +#define VAL_READ_DATA_CMD_CTRL 0x80 +#define VAL_READ_OOB_CMD_CTRL 0x4 + +#define VAL_READ_ADDR_CTRL 0x4000000 +#define VAL_READ_ADDR_CTRL_MASK 0xffffff +#define VAL_READ_DATA_CTRL 0x20000 +#define VAL_READ_DATA_CTRL_MASK 0xFFFDFFFF + +#define VAL_INTERRUPT_RESET 0xff + +#define BIT_INTERRUPT_READY 0x4 +#define BIT_STATUS_READY 0x1 \ No newline at end of file diff --git a/flash/nand/controller/qcom/niche/ascot.c b/flash/nand/controller/qcom/niche/ascot.c new file mode 100644 index 0000000..a2a6f34 --- /dev/null +++ b/flash/nand/controller/qcom/niche/ascot.c @@ -0,0 +1,216 @@ +/* Nand controller template */ +#include "../../controller.h" +#include "dcc/dn_dcc_proto.h" +#include "dcc/plat.h" + +static uint16_t tempvar; +#define ASCOT_CTRL 0x0298030C + +void inline ASCOT_SetFunction(uint8_t data, uint16_t set, uint16_t bitmask) +{ + WRITE_U16(data, (tempvar & ~set) | (set & bitmask)); + tempvar = (tempvar & ~set) | (set & bitmask); +} + +void inline ASCOT_SetFunction_NoTemp(uint8_t data, uint16_t set, uint16_t bitmask) +{ + // *offset = *offset & ~set | set & bitmask; + WRITE_U16(data, (READ_U16(data) & ~set) | (set & bitmask)); +} + +void inline ASCOT_SetBitMask(uint32_t offset, uint16_t set, uint16_t bitmask) +{ + WRITE_U16(offset, (READ_U16(offset) & ~set) | (set & bitmask)); +} + +void inline ASCOT_SetBitMask_Temp(uint32_t offset, uint16_t set, uint16_t bitmask) +{ + WRITE_U16(offset, (READ_U16(offset) & ~set) | (set & bitmask)); +} + +void inline ASCOT_Open(int index) { + ASCOT_SetBitMask(ASCOT_CTRL, 1, 1); +} + +void inline NAND_Ctrl_Command_Write(uint8_t cmd) { + // Write command routines + wdog_reset(); + // GPIO 29 + MSM5100_GPIO_Write(29, 1); + WRITE_U16(0x00800000, cmd); + MSM5100_GPIO_Write(29, 0); + +} + +void inline NAND_Ctrl_Address_Write(uint8_t addr) { + // Write address routines + wdog_reset(); + // GPIO 28 + MSM5100_GPIO_Write(28, 1); + WRITE_U16(0x00800000, addr); + MSM5100_GPIO_Write(28, 0); + +} + +uint16_t inline NAND_Ctrl_Data_Read() { + // Data read routines + wdog_reset(); + return READ_U16(0x00800000); +} + +void inline NAND_Ctrl_Wait_Ready() { + // Busy assert routines + // GPIO 6 + do { wdog_reset(); } while ( !MSM5100_GPIO_Read(6) ); +} + +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; +} \ No newline at end of file diff --git a/makefile b/makefile index ebb47fd..2537f2b 100644 --- a/makefile +++ b/makefile @@ -110,9 +110,8 @@ ifeq ($(NO_COMPRESS), 1) DDEFS += -DDISABLE_COMPRESS=1 endif -ifeq ($(NO_PIC), 1) -DADEFS += -DNO_PIC -else +ifeq ($(PIC), 1) +DADEFS += -DUSE_PIC ADD_DEPS += dcc/pic.c endif @@ -145,21 +144,24 @@ ADEFS = $(DADEFS) $(UADEFS) -DADEFS="\"FLAGS=$(DADEFS) $(UADEFS) CPU=$(MCU)\"" OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) LIBS = $(DLIBS) $(ULIBS) MCFLAGS = -mcpu=$(MCU) +CC_PIC = +AS_PIC = ifeq ($(BIG_ENDIAN), 1) MCFLAGS += -mbig-endian -mbe32 endif -ifeq ($(NO_PIC), 1) -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -c -CPFLAGS = $(MCFLAGS) -I . $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -c -LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=build/$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) -else -ASFLAGS = $(MCFLAGS) -fPIC -mpic-register=r9 -mpic-data-is-text-relative -msingle-pic-base -fPIE -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -c -CPFLAGS = $(MCFLAGS) -fPIC -mpic-register=r9 -mpic-data-is-text-relative -msingle-pic-base -fPIE -I . $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -c -LDFLAGS = $(MCFLAGS) -fPIC -mpic-register=r9 -mpic-data-is-text-relative -msingle-pic-base -fPIE -pie -nostartfiles -T$(LDSCRIPT) -Wl,-Map=build/$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) +ifeq ($(PIC), 1) +CC_PIC += -fPIC -mpic-register=r9 -mpic-data-is-text-relative -msingle-pic-base -fPIE +AS_PIC += -fPIC -mpic-register=r9 -mpic-data-is-text-relative -msingle-pic-base -fPIE -pie endif +ASFLAGS = $(MCFLAGS) $(CC_PIC) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -c +#CPFLAGS = $(MCFLAGS) $(CC_PIC) -I . $(OPT) -g -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -c +CPFLAGS = $(MCFLAGS) $(CC_PIC) -I . $(OPT) -g -gdwarf-2 -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -c +LDFLAGS = $(MCFLAGS) $(AS_PIC) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=build/$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) + + # Generate dependency information #CPFLAGS += -MD -MP -MF .dep/$(@F).d @@ -222,10 +224,9 @@ endif $(info $(NULL) BUFFER_SIZE=(Buffer Size) = DCC Buffer Size (Default: 0x40000)) $(info $(NULL) PROJECT=(name) = Output name) $(info $(NULL) LDSCRIPT=(ld) = Linker script) - $(info $(NULL) NEW_IO=1 = Use new DCC IO routines, RLE currently doesn't work in RIFF) $(info $(NULL) NO_COMPRESS=1 = Disable RLE compression, used if using with RIFF says failed to unpack received data.) $(info $(NULL) BIG_ENDIAN=1 = Big endian format) - $(info $(NULL) NO_PIC=1 = Disable PIC support) + $(info $(NULL) PIC=1 = Use PIC code) $(info Flash devices:) $(info $(NULL) CFI=1 = Enable CFI interface) $(info $(NULL) NAND_CONTROLLER=(name) = Enable NAND controller)