⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 board.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
字号:
#include <target/herrno.h>#include <target/htypes.h>#include <target/io.h>#include <target/mem.h>#include <target/str.h>#include <target/memzero.h>#include <target/flash.h>#if defined(ENABLE_ETH)#include <target/net/mac.h>#endif#include <mx3/ioregs.h>#include "memregions.h"#include "board.h"#include <target/param.h>char target_name[256];char *target_profile = target_name;struct board_info board_info;/**************************************************************************** * i.MX31 common function ****************************************************************************/void mxc_set_mux(u32 mux, u32 config){	u32 offset = (mux & ~0x03);	u32 field = (mux & 0x03);	u32 val;	if (mux < 0x00c || 0x153 < mux) 		return; /* Invalid mux */	val = IO_IOMUXC(WORD, offset);	val = (val & ~(0xff << (field * 8)));	val |= ((config & 0xff) << (field * 8));	IO_IOMUXC(WORD, offset) = val;  }u32mxc_get_mux(u32 mux){	u32 offset = (mux & ~0x03);	u32 field = (mux & 0x03);	u32 val;	if (mux < 0x00c || 0x153 < mux) 		return -1; /* Invalid mux */	val = IO_IOMUXC(WORD, offset);	return ((val >> (field * 8)) & 0xff);}void mxc_set_pad(u32 pad, u32 config){	u32 offset = (pad & ~0x03);	u32 field = (pad & 0x03);	u32 val;	if (pad < 0x154 || 0x30a < pad)		return; /* Invalid pad */	if (field >= 0x3)		return; /* Invalid field */	val = IO_IOMUXC(WORD, offset);	val = (val & ~(0x3ff << (field * 10)));	val |= ((config & 0x3ff) << (field * 10));	IO_IOMUXC(WORD, offset) = val;}intmxc_get_gpio(u32 gpio){	u32 offset = (gpio / 32);	u32 field = (gpio % 32);	u32 psr;	u32 base_addr[3] = { GPIO1_BASE_ADDR,			     GPIO2_BASE_ADDR,			     GPIO3_BASE_ADDR };	if (offset > 2)		return -1; /* Invalid */	psr = IO_WORD(base_addr[offset] + PSR);	return ((psr & (1 << field)) != 0);}voidmxc_set_gpio(u32 gpio, u32 direction, u32 data){	u32 offset = (gpio / 32);	u32 field = (gpio % 32);	u32 dr, gdir;	u32 base_addr[3] = { GPIO1_BASE_ADDR,			     GPIO2_BASE_ADDR,			     GPIO3_BASE_ADDR };	if (offset > 2)		return; /* Invalid */	gdir = IO_WORD(base_addr[offset] + GDIR);	gdir &= (~(1 << field));	gdir |= ((direction ? 1 : 0) << field);	IO_WORD(base_addr[offset] + GDIR) = gdir;	if (direction) {		dr = IO_WORD(base_addr[offset] + DR);		dr &= (~(1 << field));		dr |= ((data ? 1 : 0) << field);		IO_WORD(base_addr[offset] + DR) = dr;	}}/**************************************************************************** * armadillo5x0 init function ****************************************************************************/static void init_mux(void){	/* Jumper */	mxc_set_mux(MUX_PIN(xJP1), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xJP2), MUX_O_GPIO | MUX_I_GPIO);	/* CPU ID */	mxc_set_mux(MUX_PIN(xCPU1), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xCPU2), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xCPU3), MUX_O_GPIO | MUX_I_GPIO);	/* LED & BASE ID */	mxc_set_mux(MUX_PIN(xLED1), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xLED2), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xLED3), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xLED4), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_mux(MUX_PIN(xLED5), MUX_O_GPIO | MUX_I_GPIO);	/* UART1 */	mxc_set_mux(MUX_PIN(RXD1), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(TXD1), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(CTS1), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(RTS1), MUX_O_FUNC | MUX_I_FUNC);	/* UART2 */	mxc_set_mux(MUX_PIN(RXD2), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(TXD2), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(CTS2), MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(RTS2), MUX_O_FUNC | MUX_I_FUNC);	/* CF */	mxc_set_mux(MUX_PIN(xCF_PWREN), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_gpio(GPIO_PIN(xCF_PWREN), GPIO_OUTPUT, GPIO_HIGH);/* OFF */}static void init_weim(void){	/* GPR Setting */	IO_IOMUXC(WORD, GPR) = 0x00002000;	/* CS3: smc911x */	IO_WEIM(WORD, CSCR3U) = 0x00004803;	IO_WEIM(WORD, CSCR3L) = 0x24002531;	IO_WEIM(WORD, CSCR3A) = 0x00240000;  }#define B9600 9600#define B115200 115200static voidinit_uart(void){	u32 uart_base[2] = {UART1_BASE_ADDR, UART2_BASE_ADDR};	int baud = B115200;	int i;	/* periferal clock(ipg_per_clk) use USB clock source(60MHz) */	IO_CCM(WORD, CCMR) &= ~(CCMR_PERCS);	for (i=0; i<2; i++) {		IO_WORD(uart_base[i] + UCR3)	= 0x0704;		IO_WORD(uart_base[i] + UFCR)	= 0x0a01;		IO_WORD(uart_base[i] + ONEMS)	= 0x81ea;		switch(baud){		case B115200:		default:			IO_WORD(uart_base[i] + UBIR)	= 0x0fa2;			IO_WORD(uart_base[i] + UBMR)	= 0xfe80;			break;		}			IO_WORD(uart_base[i] + UCR1)	= (UCR1_UARTEN);		IO_WORD(uart_base[i] + UCR2)	= (UCR2_RXEN | UCR2_TXEN |						   0x4021);		IO_WORD(uart_base[i] + USR2)	= 0xffff;		IO_WORD(uart_base[i] + USR1)	= 0xffff;	}}static voidinit_i2c(void){	int i;	u32 old_mux;	old_mux = mxc_get_mux(MUX_PIN(CSPI2_MOSI));	mxc_set_mux(MUX_PIN(CSPI2_MOSI), MUX_O_FUNC | MUX_I_FUNC);	IO_CSPI2(WORD, CONREG) = 0x00071f0b;	for (i=0; i<8; i++) {		/* wait TxFIFO empty */		while (!(IO_CSPI2(WORD, STATREG) & 0x0001));		IO_CSPI2(WORD, TXDATA) = 0x55555555;	}	/* wait busy */	while (!(IO_CSPI2(WORD, STATREG) & 0x0100));	IO_CSPI2(WORD, STATREG) = 0x0100;	IO_CSPI2(WORD, CONREG) = 0x0;	mxc_set_mux(MUX_PIN(CSPI2_MOSI), old_mux); }/**************************************************************************** *  ****************************************************************************/intchange_clk(u32 clk, u32 clkss){	u32 ccmr;	u32 prcs;	u32 mpctl;	u32 pdr0;	ccmr = IO_CCM(WORD, CCMR);	prcs = (ccmr & CCMR_PRCS);	switch(clk){	case CLK_399MHZ:		pdr0 = PDR0_399MHZ;		mpctl = ((prcs == PRCS_FPM) ?			 MPCTL_FPM_399 : MPCTL_CKIH_399);		break;	case CLK_532MHZ:		pdr0 = PDR0_532MHZ;		mpctl = ((prcs == PRCS_FPM) ?			 MPCTL_FPM_532 : MPCTL_CKIH_532);		break;	default:		return -1;	}	IO_CCM(WORD, CCMR)  = ((ccmr & ~(CCMR_MPE | CCMR_SPE | CCMR_UPE)) | 			       CCMR_MDS);	IO_CCM(WORD, PDR0)  = pdr0;	IO_CCM(WORD, MPCTL) = mpctl;	IO_CCM(WORD, CCMR)  = ccmr;	return 0;}/**************************************************************************** * LED function ****************************************************************************/void led_on(void){	mxc_set_gpio(GPIO_PIN(xLED5), 1, 1);}void led_off(void){	mxc_set_gpio(GPIO_PIN(xLED5), 1, 0);}/**************************************************************************** * DELAY function **************************************************************************** * Note. *   __udelay() : just a temperary implementation. ****************************************************************************/#define UDELAY_TIC_399MHz (5)#define UDELAY_TIC (UDELAY_TIC_399MHz)#define __udelay()                           \({                                           \	__asm__ volatile (                   \		"	mov r0, %0;"         \		"udelay_loop:"               \		"	subs r0, r0, #0x01;" \		"	bne udelay_loop;"    \		:                            \		: "r" (UDELAY_TIC)           \		: "r0", "memory"             \		);                           \})voidudelay(unsigned long usec){	while (usec--)		__udelay();}voidmdelay(unsigned long msec){	while (msec--)		udelay(1000);}/**************************************************************************** *  ****************************************************************************/int is_autoboot_mode(void){	return (!board_info.jumper1);}/**************************************************************************** * get_board_info ****************************************************************************/static int get_board_info(void){	memzero(&board_info, sizeof(struct board_info));	/* Jumper */	mxc_set_gpio(GPIO_PIN(xJP1), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xJP2), GPIO_INPUT, 0);	board_info.jumper1 = mxc_get_gpio(GPIO_PIN(xJP1)) ? 0 : 1;	board_info.jumper2 = mxc_get_gpio(GPIO_PIN(xJP2)) ? 0 : 1;	/* CPU Board ID */	mxc_set_gpio(GPIO_PIN(xCPU1), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xCPU2), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xCPU3), GPIO_INPUT, 0);	board_info.cpu_board_id = mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 0):0;	board_info.cpu_board_id |= mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 1):0;	board_info.cpu_board_id |= mxc_get_gpio(GPIO_PIN(xCPU1)) ? (1 << 2):0;	/* BASE Board ID */	mxc_set_gpio(GPIO_PIN(xID1), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xID2), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xID3), GPIO_INPUT, 0);	mxc_set_gpio(GPIO_PIN(xID4), GPIO_INPUT, 0);	board_info.base_board_id = mxc_get_gpio(GPIO_PIN(xID1)) ? (1 << 0):0;	board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID2)) ? (1 << 1):0;	board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID3)) ? (1 << 2):0;	board_info.base_board_id |= mxc_get_gpio(GPIO_PIN(xID4)) ? (1 << 3):0;	mxc_set_gpio(GPIO_PIN(xID1), GPIO_OUTPUT, 0);	mxc_set_gpio(GPIO_PIN(xID2), GPIO_OUTPUT, 0);	mxc_set_gpio(GPIO_PIN(xID3), GPIO_OUTPUT, 0);	mxc_set_gpio(GPIO_PIN(xID4), GPIO_OUTPUT, 0);	return 0;}/**************************************************************************** *  ****************************************************************************/static char *get_board_name(u32 id){	return "Armadillo-500";}static voidupdate_target_profile(void){	int len;	memset(target_name, 0, TARGET_NAME_LEN);	len = strlen(get_board_name(0));	strcpy(&target_name[0], get_board_name(0));	if (strlen(PROFILE_STRING)) {		target_name[len] = '/';		strcpy(&target_name[len + 1], PROFILE_STRING);		target_name[len + 1 + strlen(PROFILE_STRING)] = 0; /* NULL */	}}/**************************************************************************** * board_init ****************************************************************************/void board_init(void){	int ch;	init_mux();	init_weim();	init_uart();	init_i2c();	/* get board info */	get_board_info();	/* update target_profile string */	update_target_profile();#if defined(RELOCATE)	/* serial function initialize */	if (check_param("console=ttymxc0"))	  ch = 1;	else if (check_param("console=ttymxc1"))	  ch = 2;	else if (check_param("console="))	  ch = 0;	else	  ch = 1;	if (!is_autoboot_mode())		if (ch == 0)#endif			ch = 1;	change_serial_channel(ch);	/* flash function initialize */	flash_initialize(FLASH_TYPE_INTEL, FLASH_START);}/**************************************************************************** * get_board_info ****************************************************************************/static int setbootdevice_cmdfunc(int argc, char **argv){	/* initialize parameter: bootdevice, using default flash */	if (!check_param("@bootdevice")) {		char *c_argv[2] = {argv[0], "flash"};		sethermit_param(2, c_argv, "@bootdevice");	}	if (argc > 1)		if (strcmp(argv[1], "flash") != 0 &&		    strcmp(argv[1], "hda1") != 0 &&		    strcmp(argv[1], "hda2") != 0 &&		    strcmp(argv[1], "hda3") != 0 &&		    strcmp(argv[1], "hda4") != 0 &&		    strcmp(argv[1], "hda") != 0)			return -H_EINVAL;	return sethermit_param(argc, argv, "@bootdevice");}/**************************************************************************** * get_board_info ****************************************************************************/static int setclock_cmdfunc(int argc, char *argv[]){	/* initialize parameter: clock, using default 400 */	if (!check_param("@clock")) {		char *c_argv[2] = {argv[0], "400"};		sethermit_param(2, c_argv, "@clock");	}	if (argc > 1)		if (strcmp(argv[1], "532") != 0 &&		    strcmp(argv[1], "400") != 0)			return -H_EINVAL;	return sethermit_param(argc, argv, "@clock");}/**************************************************************************** * info_cmdfunc ****************************************************************************/static intinfo_cmdfunc(int argc, char *argv[]){	hprintf("CPU Silicon Rev: %p\n", IO_IIM(WORD, SREV) & 0xff);	hprintf("CPU Board ID   : %p\n", board_info.cpu_board_id);	hprintf("BASE Board ID  : %p\n", board_info.base_board_id);	hprintf("HAB-TYPE       : %p\n", IO_IIM(WORD, HAB1) & 0x07);#if defined(ENABLE_ETH)	hprintf("MAC Address    : ");	mac_command.func(0, 0);#endif	return 0;}const command_t setbootdevice_command =	{ "setbootdevice", "<flash/hda[1:4]>", "linux kernel location", 	  &setbootdevice_cmdfunc };const command_t setclock_command =	{"setclock", "<400/532>", "set mcu_clk", &setclock_cmdfunc};const command_t info_command =        { "info", "", "display board info",          &info_cmdfunc };COMMAND_ABBR(setbootdevice_command, 'l');COMMAND(setclock_command);COMMAND(info_command);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -