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

📄 biosapi.c

📁 嵌入式linux下ARM4210板的bootloader
💻 C
字号:
#include "board.h"#include "utils.h"#include "bios.h"#include "flash.h"static struct config_table_struct config_table;static unsigned long get_rom_size(struct system_table_struct *sys_tbl){	unsigned long rom_size = 0;	int i;	for (i = 0; i < 4; i++)		rom_size += sys_tbl->rom_table[i].size;	return rom_size;}static unsigned long get_dram_size(struct system_table_struct *sys_tbl){	unsigned long dram_size = 0;	int i;	for (i = 0; i < 4; i++)		dram_size += sys_tbl->dram_table[i].size;	return dram_size;}static int get_uart0_cfg(struct system_table_struct *sys_tbl, struct uart_cfg *cfg){	struct sys_uart_cfg *uart = (struct sys_uart_cfg *)&sys_tbl->uart[0];	cfg->flags = uart->flags;	if (uart->port == 0) {		cfg->base = ULCON0;		cfg->irq_rx = INT_UARTRX0;		cfg->irq_tx = INT_UARTTX0;	} else if (uart->port == 1) {		cfg->base = ULCON1;		cfg->irq_rx = INT_UARTRX1;		cfg->irq_tx = INT_UARTTX1;	} else {		cfg->base = -1;		cfg->irq_rx = -1;		cfg->irq_tx = -1;	}	cfg->dma_rx = uart->dma_rx;	cfg->dma_tx = uart->dma_tx;	cfg->mode = uart->mode;	return 0;}static int get_uart1_cfg(struct system_table_struct *sys_tbl, struct uart_cfg *cfg){	struct sys_uart_cfg *uart = (struct sys_uart_cfg *)&sys_tbl->uart[1];	cfg->flags = uart->flags;	if (uart->port == 0) {		cfg->base = ULCON0;		cfg->irq_rx = INT_UARTRX0;		cfg->irq_tx = INT_UARTTX0;	} else if (uart->port == 1) {		cfg->base = ULCON1;		cfg->irq_rx = INT_UARTRX1;		cfg->irq_tx = INT_UARTTX1;	} else {		cfg->base = -1;		cfg->irq_rx = -1;		cfg->irq_tx = -1;	}	cfg->dma_rx = uart->dma_rx;	cfg->dma_tx = uart->dma_tx;	cfg->mode = uart->mode;	return 0;}static int get_eth_cfg(struct system_table_struct *sys_tbl, struct eth_cfg *cfg){	struct sys_eth_cfg *eth = (struct sys_eth_cfg *)&sys_tbl->eth;	cfg->flags = eth->flags;	cfg->base = BDMATXCON;	memcpy(cfg->address, eth->address, 6);	return 0;}static int get_ne2000_cfg(struct system_table_struct *sys_tbl, struct ne2000_cfg *cfg){	struct sys_ne2000_cfg *ne2000 = (struct sys_ne2000_cfg *)&sys_tbl->ne2000;	cfg->flags = ne2000->flags;	cfg->base = sys_tbl->ext_base + ne2000->bank * 0x4000;	memcpy(cfg->address, ne2000->address, 6);	return 0;}
static int get_uart16550_cfg(struct system_table_struct *sys_tbl, struct uart16550_cfg *cfg){	struct sys_uart16550_cfg *uart16550 = (struct sys_uart16550_cfg *)&sys_tbl->uart16550;	cfg->flags = uart16550->flags;	cfg->base = sys_tbl->ext_base + uart16550->bank * 0x4000;	cfg->clock = uart16550->clock;	return 0;}
static int get_pc97338_cfg(struct system_table_struct *sys_tbl, struct pc97338_cfg *cfg){	struct sys_uart16550_cfg *pc97338 = (struct sys_uart16550_cfg *)&sys_tbl->pc97338;	cfg->flags = pc97338->flags;	cfg->base = sys_tbl->ext_base + pc97338->bank * 0x4000;	return 0;}static int reboot(void){	void (*fp)(void);
	fp = (void (*)(void))(config_table.rom_base);
	(*fp)();	return 0;
}static int bios_call_init(struct biosapi_init_struct *init_param){	struct system_table_struct *sys_tbl;	sys_tbl = (struct system_table_struct *)		(init_param->rom_base + init_param->system_table_offset);	memset(&config_table, 0, sizeof(struct config_table_struct));	config_table.vendor_id = sys_tbl->vendor_id;	config_table.device_id = sys_tbl->device_id;	config_table.sub_vendor_id = sys_tbl->sub_vendor_id;	config_table.sub_device_id = sys_tbl->sub_device_id;	config_table.rev = sys_tbl->rev;	config_table.sys_clock = sys_tbl->sys_clock;	config_table.ext_clock = sys_tbl->ext_clock;	config_table.rom_base = init_param->rom_base;	config_table.rom_size = get_rom_size(sys_tbl);	config_table.bios_offset = 0;	config_table.bios_size = sys_tbl->bios_size;	config_table.system_table_offset = init_param->system_table_offset;	config_table.system_table_size = sys_tbl->system_table_size;	config_table.partition_table_offset = sys_tbl->partition_table_offset;	config_table.partition_table_size = sys_tbl->partition_table_size;	config_table.dram_base = init_param->dram_base;	config_table.dram_size = get_dram_size(sys_tbl);	get_uart0_cfg(sys_tbl, &config_table.uart[0]);	get_uart1_cfg(sys_tbl, &config_table.uart[1]);	get_eth_cfg(sys_tbl, &config_table.eth);	get_ne2000_cfg(sys_tbl, &config_table.ne2000);	get_pc97338_cfg(sys_tbl, &config_table.pc97338);	get_uart16550_cfg(sys_tbl, &config_table.uart16550);	config_table.startup_mode = sys_tbl->startup_mode;	config_table.tftp_ipaddr = sys_tbl->tftp_ipaddr;	flash_init();	return 0;}int bios_call_internal(unsigned long id, unsigned long arg)
{	switch (id) {	case BIOSCALL_INIT:		bios_call_init((struct biosapi_init_struct *)arg);		break;	case BIOSCALL_REBOOT:		reboot();		break;	case BIOSCALL_GET_VENDORID:		*(unsigned short *)arg = config_table.vendor_id;		break;	case BIOSCALL_GET_DEVICEID:		*(unsigned short *)arg = config_table.device_id;		break;	case BIOSCALL_GET_SUBVENDORID:		*(unsigned short *)arg = config_table.sub_vendor_id;		break;	case BIOSCALL_GET_SUBDEVICEID:		*(unsigned short *)arg = config_table.sub_device_id;		break;	case BIOSCALL_GET_REV:		*(unsigned long *)arg = config_table.rev;		break;	case BIOSCALL_GET_SYSCLOCK:		*(unsigned long *)arg = config_table.sys_clock;		break;	case BIOSCALL_GET_EXTCLOCK:		*(unsigned long *)arg = config_table.ext_clock;		break;	case BIOSCALL_GET_ROMBASE:		*(unsigned long *)arg = config_table.rom_base;		break;	case BIOSCALL_GET_ROMSIZE:		*(unsigned long *)arg = config_table.rom_size;		break;	case BIOSCALL_GET_DRAMBASE:		*(unsigned long *)arg = config_table.dram_base;		break;	case BIOSCALL_GET_DRAMSIZE:		*(unsigned long *)arg = config_table.dram_size;		break;	case BIOSCALL_GET_BIOSOFFSET:		*(unsigned long *)arg = config_table.bios_offset;		break;	case BIOSCALL_GET_BIOSSIZE:		*(unsigned long *)arg = config_table.bios_size;		break;	case BIOSCALL_GET_SYSTEMTABLEOFFSET:		*(unsigned long *)arg = config_table.system_table_offset;		break;	case BIOSCALL_GET_SYSTEMTABLESIZE:		*(unsigned long *)arg = config_table.system_table_size;		break;	case BIOSCALL_GET_PARTITIONTABLEOFFSET:		*(unsigned long *)arg = config_table.partition_table_offset;		break;	case BIOSCALL_GET_PARTITIONTABLESIZE:		*(unsigned long *)arg = config_table.partition_table_size;		break;	case BIOSCALL_FLASH_ERASE:		flash_erase(((struct flash_erase_struct *)arg)->addr,			((struct flash_erase_struct *)arg)->size);		break;	case BIOSCALL_FLASH_READ:		flash_read(((struct flash_read_struct *)arg)->from,			((struct flash_read_struct *)arg)->len,			&(((struct flash_read_struct *)arg)->retlen),			((struct flash_read_struct *)arg)->buf);		break;	case BIOSCALL_FLASH_WRITE:		flash_write(((struct flash_write_struct *)arg)->to,			((struct flash_write_struct *)arg)->len,			&(((struct flash_write_struct *)arg)->retlen),			((struct flash_write_struct *)arg)->buf);		break;	case BIOSCALL_GET_UART0CFG:		*(struct uart_cfg *)arg = config_table.uart[0];		break;	case BIOSCALL_GET_UART1CFG:		*(struct uart_cfg *)arg = config_table.uart[1];		break;	case BIOSCALL_GET_ETHCFG:		*(struct eth_cfg *)arg = config_table.eth;		break;	case BIOSCALL_GET_NE2000CFG:		*(struct ne2000_cfg *)arg = config_table.ne2000;		break;	case BIOSCALL_GET_PC97338CFG:		*(struct pc97338_cfg *)arg = config_table.pc97338;		break;	case BIOSCALL_GET_UART16550CFG:		*(struct uart16550_cfg *)arg = config_table.uart16550;		break;	case BIOSCALL_GET_STARTUPMODE:		*(unsigned long *)arg = config_table.startup_mode;		break;	case BIOSCALL_GET_TFTPIPADDR:		*(unsigned long *)arg = config_table.tftp_ipaddr;		break;	default:		return -1;	}	return 0;}

⌨️ 快捷键说明

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