📄 stage1_boot.c
字号:
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef unsigned short uint16;
#define NAND_NO_DATA
#include "SMC.h"
#define NAND_BUS_WIDTH 8
// #define NAND_CS_DONT_CARE
#define PAGE_COUNT 31
#define PAGE_SIZE 512
#define GPIO_REG_OUTPUT *(uint32*)(0xB1700008)
#define NAND_FORCE_CE 15
//****************************************
// Nand Registers //
//#define NAND_PHYS_ADDR 0x20000000
#define NAND_PHYS_ADDR 0x08000000
#define NAND_CS 0xA8000000 //Mapped chip select address
#define NAND_REG_CMD *(volatile short*)(NAND_CS + MEM_STNAND_CMD)
#define NAND_REG_ADDR *(volatile short*)(NAND_CS + MEM_STNAND_ADDR)
#define NAND_REG_DATA *(volatile short*)(NAND_CS + MEM_STNAND_DATA)
//****************************************
//****************************************
// Nand Commands //
#define NAND_CMD_AUTO_ERASE_SETUP 0x0060
#define NAND_CMD_ERASE 0x00D0
#define NAND_CMD_STATUS_READ1 0x0070
#define NAND_CMD_STATUS_READ2 0x0071
#define NAND_CMD_SEQ_DATA_INPUT 0x0080
#define NAND_CMD_PROGRAM 0x0010
#define NAND_CMD_READ1 0x0000
#define NAND_CMD_READ2 0x0001
#define NAND_CMD_READ3 0x0050
#define NAND_CMD_RESET 0x00FF
#define NAND_CMD_ID_READ1 0x0090
#define NAND_CMD_ID_READ2 0x0091
//****************************************
//****************************************
// Nand Status //
#define NAND_STATUS_PROGRAM_ERROR 0x01
#define NAND_STATUS_ERASE_ERROR 0x01
//****************************************
// Nand Static Bus Configuration //
//Timing values as described in databook, ns value stripped of lower 2 bits
#define NAND_T_H (18 >> 2)
#define NAND_T_PUL (30 >> 2)
#define NAND_T_SU (30 >> 2)
#define NAND_T_WH (30 >> 2)
//Bitfield shift amounts
#define NAND_T_H_SHIFT 0
#define NAND_T_PUL_SHIFT 4
#define NAND_T_SU_SHIFT 8
#define NAND_T_WH_SHIFT 12
#define NAND_TIMING ((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT)
#define NAND_CTRL_BOOT 1
#define NAND_CTRL_INTERRUPT (1<<8)
#define NAND_CTRL_CS_OVERIDE 0x20
#define NAND_STSTAT_RNB 0x01
//Static bus configuration registers
#define NAND_ADDR_SPACE_SIZE 0x3FF
#define NAND_SB_CSBA(n) ((n >> 4) & 0x0FFFC000)
#define NAND_SB_CSMASK(n) (n<<4)
#define NAND_SB_ENABLE (1<<28)
#define NAND_SB_REG_TIMING *(uint32*)(SMC_PHYS_ADDRESS + SMC_MEMSTTIME1)
#define NAND_SB_REG_CONFIG *(uint32*)(SMC_PHYS_ADDRESS + SMC_MEMSTCFG1)
#define NAND_SB_REG_ADDR *(uint32*)(SMC_PHYS_ADDRESS + SMC_STADDR1)
#define NAND_SB_REG_CTRL *(uint32*)(SMC_PHYS_ADDRESS + MEM_STNAND)
#define NAND_SB_REG_STSTAT *(uint32*)(SMC_PHYS_ADDRESS + MEM_STSTAT)
//****************************************
static void __inline configure_nand()
{
//Enable Nand Force GPIO
GPIO_REG_OUTPUT = (1 << (16 + NAND_FORCE_CE)) | (1 << NAND_FORCE_CE);
//Configure Static Bus
NAND_SB_REG_CTRL = 0; // Disable nand BOOT bit
NAND_SB_REG_CONFIG = SMC_NAND;
NAND_SB_REG_TIMING = NAND_TIMING;
NAND_SB_REG_ADDR = NAND_SB_ENABLE | NAND_SB_CSBA(NAND_PHYS_ADDR) | NAND_SB_CSMASK(NAND_ADDR_SPACE_SIZE);
}
static void __inline set_address(uint16 block, uint8 page, uint8 column)
{
NAND_REG_ADDR = column;
NAND_REG_ADDR = page | ((block&(0x7)) << 5); //A9-A16
NAND_REG_ADDR = (block >> 3); //A17-A25
NAND_REG_ADDR = (block >> 11); //A25
}
static void __inline wait_busy()
{
int i;
for(i = 0; i < 10000000; ++i)
{
if(i > 1000 && (NAND_SB_REG_STSTAT & NAND_STSTAT_RNB))
{
return;
}
}
}
static void __inline read_stage2()
{
extern uint32 _stage2;
#if NAND_BUS_WIDTH == 8
char* dest = (char*) &_stage2;
#elif NAND_BUS_WIDTH == 16
short* dest = (short*) &_stage2;
#endif
int page, bytes;
NAND_REG_CMD = NAND_CMD_READ1;
#ifndef NAND_CS_DONT_CARE
NAND_SB_REG_CTRL = NAND_CTRL_CS_OVERIDE; //Manually assert CS
#endif
for(page = 1; page < PAGE_COUNT; ++page)
{
set_address(0, page, 0);
wait_busy();
for(bytes = 0; bytes < PAGE_SIZE; bytes += (NAND_BUS_WIDTH / 8))
*dest++ = NAND_REG_DATA;
}
#ifndef NAND_CS_DONT_CARE
NAND_SB_REG_CTRL = 0;
#endif
}
void __attribute__((section(".stage1"))) load_stage2()
{
// *((uint32*)0xADC00000) = 1;
configure_nand();
// *((uint32*)0xADC00000) = 2;
read_stage2();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -