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

📄 ide_a5x0.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
字号:
/* * Copyright (c) 2007 Atmark Techno, Inc.  All Rights Reserved. */#include <target/herrno.h>#include <target/htypes.h>#include <target/io.h>#include <target/buffer.h>#include <target/gunzip.h>#include <target/memzero.h>#include <target/memcmp.h>#include <mx3/ioregs.h>#include "board.h"#include "pcmcia_core.h"#include "ide_core.h"#include "ide_a5x0.h"#include "fs_ext2.h"#include "memregions.h"#include "mmu.h"#include "linux.h"#define DRIVER_NAME "ide_a5x0"#undef DEBUG#if defined(DEBUG)#define DEBUG_FUNC()        hprintf("*" DRIVER_NAME ": %s()\n", __FUNCTION__)#define DEBUG_INFO(args...) hprintf("*" DRIVER_NAME ": " args)#define DEBUG_ERR(args...)  hprintf("*" DRIVER_NAME ": " args)#else#define DEBUG_FUNC()#define DEBUG_INFO(args...)#define DEBUG_ERR(args...)#endif#define PRINT_INFO(args...) hprintf(DRIVER_NAME ": " args)#define PRINT_ERR(args...)  hprintf(DRIVER_NAME ": " args)/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_mux_init(void){	DEBUG_FUNC();	mxc_set_mux(MUX_PIN(SDBA0),     MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(SDBA1),     MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_CD1),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_CD2),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_WAIT),   MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_READY),  MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_PWRON),  MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_VS1),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_VS2),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_BVD1),   MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_BVD2),   MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_RST),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(IOIS16),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_RW),     MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(PC_POE),    MUX_O_FUNC | MUX_I_FUNC);	mxc_set_mux(MUX_PIN(xCF_PWREN), MUX_O_GPIO | MUX_I_GPIO);	mxc_set_gpio(GPIO_PIN(xCF_PWREN), GPIO_OUTPUT, GPIO_HIGH);}/**************************************************************************** * driver: ****************************************************************************/static voidpcmcia_a5x0_power_on(void){	u32 pipr;	int i;	DEBUG_FUNC();	mxc_set_gpio(GPIO_PIN(xCF_PWREN), GPIO_OUTPUT, GPIO_LOW);	for (i=0; i<100; i++) {		pipr = IO_PCMCIA(WORD, PIPR);		if (pipr & 0x100)			break;		mdelay(10);	}	mdelay(500);}/**************************************************************************** * driver: ****************************************************************************/static voidpcmcia_a5x0_power_off(void){	DEBUG_FUNC();	mxc_set_gpio(GPIO_PIN(xCF_PWREN), GPIO_OUTPUT, GPIO_HIGH);}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_reset(void){	DEBUG_FUNC();	IO_PCMCIA(WORD, PGCR) |= PGCR_RESET;	mdelay(2);	IO_PCMCIA(WORD, PGCR) &= ~(PGCR_RESET | PGCR_LPMEN);	IO_PCMCIA(WORD, PGCR) |= PGCR_POE;	mdelay(2);	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_bank_init(void){	DEBUG_FUNC();	IO_PCMCIA(WORD, POR0) &= ~POR_PV;	IO_PCMCIA(WORD, PBR0) = PCMCIA_MEM_BASE_ADDR;	IO_PCMCIA(WORD, POR0) = POR_PV | 0x11c;	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_hw_init(pcmcia_info_t *info){	DEBUG_FUNC();	pcmcia_a5x0_mux_init();	pcmcia_a5x0_power_off();	pcmcia_a5x0_reset();	pcmcia_a5x0_bank_init();	info->mem_base = PCMCIA_MEM_BASE_ADDR;	info->attr_base = PCMCIA_MEM_BASE_ADDR;	info->io_base = PCMCIA_MEM_BASE_ADDR;	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_hw_free(void){	DEBUG_FUNC();	pcmcia_a5x0_power_off();  	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_set_socket(int power){	DEBUG_FUNC();	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_get_status(void){	u32 pipr;	DEBUG_FUNC();	pipr = IO_PCMCIA(WORD, PIPR);	if (!(pipr & 0x18))		pcmcia_a5x0_power_on();	else {		pcmcia_a5x0_power_off();		return -H_EIO;	}	pipr = IO_PCMCIA(WORD, PIPR);	if (!(pipr & 0x100))		return -H_EIO;	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_set_mem_map(int map){	DEBUG_FUNC();	if (map == 1/*ATTR*/) {		IO_PCMCIA(WORD, POR0) &= ~POR_PV;		IO_PCMCIA(WORD, PBR0) = PCMCIA_MEM_BASE_ADDR;		IO_PCMCIA(WORD, POR0) &= ~(0x6000000 | 0xffffff);		IO_PCMCIA(WORD, POR0) |= (0x4000000 | POR_PV | 0x54306e);	} else {		IO_PCMCIA(WORD, POR0) &= ~POR_PV;		IO_PCMCIA(WORD, PBR0) = PCMCIA_MEM_BASE_ADDR;		IO_PCMCIA(WORD, POR0) &= ~(0x6000000 | 0xffffff);		IO_PCMCIA(WORD, POR0) |= (0x0000000 | POR_PV | 0x54306e);	}	return 0;}/**************************************************************************** * driver: ****************************************************************************/static intpcmcia_a5x0_set_io_map(int map){	DEBUG_FUNC();	IO_PCMCIA(WORD, POR0) &= ~POR_PV;	IO_PCMCIA(WORD, PBR0) = PCMCIA_MEM_BASE_ADDR;	IO_PCMCIA(WORD, POR0) &= ~(0x6000000 | 0xffffff);	IO_PCMCIA(WORD, POR0) |= (0x6000000 | POR_PV | 0x30606e);	return 0;}/**************************************************************************** * driver: ****************************************************************************/static pcmcia_ops_t a5x0_pcmcia_ops = {	.hw_init	= pcmcia_a5x0_hw_init,	.hw_free	= pcmcia_a5x0_hw_free,	.set_socket	= pcmcia_a5x0_set_socket,	.get_status	= pcmcia_a5x0_get_status,	.set_mem_map	= pcmcia_a5x0_set_mem_map,	.set_io_map	= pcmcia_a5x0_set_io_map,};/**************************************************************************** * driver: ****************************************************************************/static ide_info_t a5x0_ide_info = {	.ext_probe	= pcmcia_probe,	.ext_remove	= pcmcia_remove,	.ext_priv	= (void *)&a5x0_pcmcia_ops,	.devid		= 0,	.data_port	= PCMCIA_MEM_BASE_ADDR,	.ctrl_port	= PCMCIA_MEM_BASE_ADDR + 0xe,};/**************************************************************************** * application: ****************************************************************************/#define CHECK_ERR(ret, label) \({                            \	if ((ret) < 0)        \		goto label;   \})/**************************************************************************** * application: ****************************************************************************/intide_load_kernel(int device){	ide_info_t *info = &a5x0_ide_info;	partition_t partitions[4];	file_t file;	u8 buf[SECTOR_SIZE * 8];	int success = 0;	int loop_start, loop_end;	int ret = 0;	int i;	DEBUG_FUNC();	ret = ide_probe(info);	CHECK_ERR(ret, err_probe);	ret = info->startup(info);	CHECK_ERR(ret, err_startup);	ret = info->read_sectors(info, 0, buf, 1);	CHECK_ERR(ret, err_read_sector);	if (device == 0) {		loop_start = 0;		loop_end = 4;	} else {		loop_start = device - 1;		loop_end = device;	}	memcpy(partitions, buf + 0x1be, sizeof(partition_t) * 4);	for (i=loop_start; i<loop_end; i++) {		memzero(&file, sizeof(file_t));		ret = info->find_image(info, 0, i, &partitions[i], &file);		if (ret < 0)			continue;		PRINT_INFO("%s is found. (%d Bytes)\n", file.name, file.size);		if (file.size > (INITRD_LOAD_ADDRESS - LINUX_LOAD_ADDRESS)) {			PRINT_ERR("%s size is too large.\n", file.name);			continue;		}		if (file.compressed)			/* tmp buffer addr */			file.load_addr = INITRD_LOAD_ADDRESS;		else			file.load_addr = LINUX_LOAD_ADDRESS;		ret = info->file_copy(info, &file);		if (ret == 0) {			success = 1;			break;		}	}	ide_remove(&a5x0_ide_info);	if (!success) {		PRINT_ERR("Not found bootable image.\n");		return -H_EIO;	}	boost_on(BOOST_LINUX_MODE);	if (file.compressed)		gunzip_object(" kernel",			      INITRD_LOAD_ADDRESS,			      LINUX_LOAD_ADDRESS);    	boost_off();	return 0;   err_read_sector: err_startup: err_probe:	ide_remove(&a5x0_ide_info);	return ret;}

⌨️ 快捷键说明

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