📄 ide_a5x0.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 + -