diff --git a/bsp/x86/applications/application.c b/bsp/x86/applications/application.c index 0883216976..3a2f6c9b82 100644 --- a/bsp/x86/applications/application.c +++ b/bsp/x86/applications/application.c @@ -1,100 +1,77 @@ -/** File : application.c +/* + * File : application.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Develop Team + * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://openlab.rt-thread.com/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - -* Change Logs: + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: * Date Author Notes - * 2006-09-15 QiuYi the first version + * 2009-01-05 Bernard the first version */ -/** - * @addtogroup QEMU - */ - -/*@{*/ - #include -ALIGN(RT_ALIGN_SIZE) -static char thread_led1_stack[1024]; -struct rt_thread thread_led1; -static void rt_thread_entry_led1(void *parameter) +#ifdef RT_USING_DFS +#include +#include "floppy.h" +#endif + +/* components initialization for simulator */ +void components_init(void) { - unsigned int count=0; +#ifdef RT_USING_DFS + rt_floppy_init(); + /* initialize the device file system */ + dfs_init(); - while (1) +#ifdef RT_USING_DFS_ELMFAT + /* initialize the elm chan FatFS file system*/ + elm_init(); +#endif +#endif +} +void rt_init_thread_entry(void *parameter) +{ + components_init(); + + /* File system Initialization */ +#ifdef RT_USING_DFS { - /* led1 on */ -#ifndef RT_USING_FINSH - rt_kprintf("led1 on,count : %d\r\n",count); -#endif - count ++; - /* sleep 0.5 second and switch to other thread */ - rt_thread_delay(RT_TICK_PER_SECOND / 2); - /* led1 off */ -#ifndef RT_USING_FINSH - rt_kprintf("led1 off\r\n"); +#ifdef RT_USING_DFS_ELMFAT + /* mount sd card fatfs as root directory */ + if (dfs_mount("floppy", "/", "elm", 0, 0) == 0) + rt_kprintf("fatfs initialized!\n"); + else + rt_kprintf("fatfs initialization failed!\n"); #endif - rt_thread_delay(RT_TICK_PER_SECOND / 2); } +#endif } -ALIGN(RT_ALIGN_SIZE) -static char thread_led2_stack[1024]; -struct rt_thread thread_led2; -void rt_thread_entry_led2(void *parameter) +int rt_application_init() { - unsigned int count=0; + rt_thread_t tid; - while (1) - { - /* led2 on */ -#ifndef RT_USING_FINSH - rt_kprintf("led2 on,count : %d\r\n",count); -#endif - count ++; - rt_thread_delay(RT_TICK_PER_SECOND); + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, RT_THREAD_PRIORITY_MAX / 3, 20); - /* led2 off */ -#ifndef RT_USING_FINSH - rt_kprintf("led2 off\r\n"); -#endif - rt_thread_delay(RT_TICK_PER_SECOND); - } -} - -/** - * This function will be invoked to initalize user application when system - * startup. - */ - -int rt_application_init(void) -{ - // init led1 thread - rt_thread_init(&thread_led1, - "led1", - rt_thread_entry_led1, - RT_NULL, - &thread_led1_stack[0], - sizeof(thread_led1_stack),11,5); - rt_thread_startup(&thread_led1); - - // init led2 thread - rt_thread_init(&thread_led2, - "led2", - rt_thread_entry_led2, - RT_NULL, - &thread_led2_stack[0], - sizeof(thread_led2_stack),12,5); - rt_thread_startup(&thread_led2); + if (tid != RT_NULL) + rt_thread_startup(tid); return 0; } - -/*@}*/ diff --git a/bsp/x86/drivers/dma.h b/bsp/x86/drivers/dma.h new file mode 100644 index 0000000000..f1a8563cb1 --- /dev/null +++ b/bsp/x86/drivers/dma.h @@ -0,0 +1,187 @@ +#ifndef _DMA_H +#define _DMA_H + + +#define MAX_DMA_CHANNELS 8 + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_PAGE_0 0x87 /* DMA page registers */ +#define DMA_PAGE_1 0x83 +#define DMA_PAGE_2 0x81 +#define DMA_PAGE_3 0x82 +#define DMA_PAGE_5 0x8B +#define DMA_PAGE_6 0x89 +#define DMA_PAGE_7 0x8A + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +/* + * 启用指定的DMA通道 + */ +static __inline__ void EnableDma(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(dmanr, DMA1_MASK_REG); + else + OUTB(dmanr & 3, DMA2_MASK_REG); +} + +/* + * 禁用指定的DMA通道 + */ +static __inline__ void DisableDma(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(dmanr | 4, DMA1_MASK_REG); + else + OUTB((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* + * 清空DMA 晶体计数器 + */ +static __inline__ void ClearDmaFF(unsigned int dmanr) +{ + if (dmanr<=3) + OUTB(0, DMA1_CLEAR_FF_REG); + else + OUTB(0, DMA2_CLEAR_FF_REG); +} + +/* + * 清空DMA 晶体计数器 + */ +static __inline__ void SetDmaMode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + OUTB(mode | dmanr, DMA1_MODE_REG); + else + OUTB(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* + * 设定DMA 页面寄存器 + */ +static __inline__ void SetDmaPage(unsigned int dmanr, char pagenr) +{ + switch(dmanr) { + case 0: + OUTB(pagenr, DMA_PAGE_0); + break; + case 1: + OUTB(pagenr, DMA_PAGE_1); + break; + case 2: + OUTB(pagenr, DMA_PAGE_2); + break; + case 3: + OUTB(pagenr, DMA_PAGE_3); + break; + case 5: + OUTB(pagenr & 0xfe, DMA_PAGE_5); + break; + case 6: + OUTB(pagenr & 0xfe, DMA_PAGE_6); + break; + case 7: + OUTB(pagenr & 0xfe, DMA_PAGE_7); + break; + } +} + + +/* + * 设定DMA 传输高速缓冲区地址 + */ +static __inline__ void SetDmaAddr(unsigned int dmanr, unsigned int a) +{ + SetDmaPage(dmanr, a>>16); + if (dmanr <= 3) { + OUTB( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + OUTB( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + OUTB( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + OUTB( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* + * 设定DMA 传输块数 + */ +static __inline__ void SetDmaCount(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + OUTB( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + OUTB( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + OUTB( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + OUTB( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* + * 获得DMA 传输剩余块数 + */ +static __inline__ int GetDmaResidue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + count = 1 + inb(io_port); + count += inb(io_port) << 8; + return (dmanr<=3)? count : (count<<1); +} + +#endif + diff --git a/bsp/x86/drivers/floppy.c b/bsp/x86/drivers/floppy.c new file mode 100644 index 0000000000..058bf1b941 --- /dev/null +++ b/bsp/x86/drivers/floppy.c @@ -0,0 +1,360 @@ + +#include +#include + +#include + +typedef rt_uint8_t u8; +typedef rt_uint16_t u16; +typedef rt_uint32_t u32; + +typedef rt_int8_t s8; +typedef rt_int16_t s16; +typedef rt_int32_t s32; + +#define OUTB(v,p) outb(p,v) + +#include "floppy.h" +#include "dma.h" + +#define NULL RT_NULL +#define SECTOR_SIZE 512 +#define panic(str,...) do { rt_kprintf("panic::" str,##__VA_ARGS__); while(1); } while(0) + +#define _local_irq_save(level) level = rt_hw_interrupt_disable() +#define _local_irq_restore(level) rt_hw_interrupt_enable(level) + +static u8 floppy_buffer[512]; /* 软盘高速缓冲区地址指针 */ + +#define MAX_REPLIES 7 +static u8 floppy_reply_buffer[MAX_REPLIES]; /* 软驱回应缓冲区 */ +#define ST0 (floppy_reply_buffer[0]) /* 软驱回应0号字节 */ +#define ST1 (floppy_reply_buffer[1]) /* 软驱回应1号字节 */ +#define ST2 (floppy_reply_buffer[2]) /* 软驱回应2号字节 */ +#define ST3 (floppy_reply_buffer[3]) /* 软驱回应3号字节 */ + + +static char *floppy_inc_name; /* 软驱型号名 */ +static char *floppy_type; +static u32 floppy_motor=0; /* 软驱马达状态字节 */ +static u32 floppy_size =0; +/**********************功能函数***************************/ +static void floppy_result(void); /* 获得软驱响应状态 */ +static u32 floppy_sendbyte(u32); /* 向软驱控制寄存器发送一个控制字节 */ +static u32 floppy_getbyte(void); /* 从软驱数据寄存器得到一个数据字节 */ +static u32 floppy_get_info(void); /* 得到软驱信息 */ +static void floppy_motorOn(void); /* 打开软驱马达 */ +static void floppy_motorOff(void); /* 关闭软驱马达 */ +static void floppy_setmode(void); /* 软驱模式设置 */ +static void block_to_hts(u32, u32*, u32*, u32*); /* 逻辑块转为磁盘头、磁道号和扇区号 */ +static void floppy_setupDMA(void); /* 设置软驱DMA通道 */ +static void floppy_read_cmd(u32 blk); /* 从软盘上读取指定的逻辑块到缓冲区 */ + + +void floppy_result(void) +{ + u8 stat, i,count; + i=0; + for(count=0; count<0xFF; count++) + { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器 + if (stat == STATUS_READY) + return; + if (stat == (STATUS_READY|STATUS_DIR|STATUS_BUSY)) + { + if(i>7) break; + floppy_reply_buffer[i++]=inb_p(FD_DATA); + } + } + + panic("Get floppy status times out !\n"); +} + +u32 floppy_sendbyte( u32 value ) +{ + u8 stat, i; + + for ( i = 0; i < 128; i++ ) { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR); //读取状态寄存器 + if ( stat == STATUS_READY ) + { + OUTB( value ,FD_DATA); //将参数写入数据寄存器 + return 1; + } + io_delay(); // 作一些延迟 + } + return 0; +} + + +u32 floppy_getbyte(void) +{ + u8 stat, i; + + for ( i = 0; i < 128; i++ ) { + stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器 + if (stat == STATUS_READY) + return -1; + if ( stat == 0xD0 ) + return inb(FD_DATA); + io_delay(); + } + return 0; +} + + +u32 floppy_get_info(void) +{ + u32 i; + u8 CmType, FdType; + + floppy_sendbyte(0x10); + i = floppy_getbyte(); + + switch (i) + { + case 0x80: floppy_inc_name = "NEC765A controller"; break; + case 0x90: floppy_inc_name = "NEC765B controller"; break; + default: floppy_inc_name = "Enhanced controller"; break; + } + + CmType = readcmos(0x10); //read floppy type from cmos + FdType = (CmType>>4) & 0x07; + + if ( FdType == 0 ) + panic("Floppy driver not found!"); + + switch( FdType ) + { + case 0x02: // 1.2MB + floppy_type = "1.2MB"; + floppy_size = 2458*512; + break; + + case 0x04: // 1.44MB 标准软盘 + floppy_type = "1.44MB"; + floppy_size = 2880*512; + break; + + case 0x05: // 2.88MB + floppy_type = "2.88MB"; + floppy_size = 2*2880*512; + break; + } + return 1; +} + + +void floppy_motorOn( void ) +{ + u32 eflags; + if (!floppy_motor) + { + _local_irq_save(eflags); + OUTB(28,FD_DOR); + floppy_motor = 1; + _local_irq_restore(eflags); + } + return; +} + + +void floppy_motorOff( void ) +{ + u32 eflags; + if (floppy_motor) + { + _local_irq_save(eflags); + OUTB(12,FD_DOR); + floppy_motor = 0; + _local_irq_restore(eflags); + + } + return; +} + + +void floppy_setmode(void) +{ + floppy_sendbyte (FD_SPECIFY); + floppy_sendbyte (0xcf); + floppy_sendbyte (0x06); + OUTB (0,FD_DCR); +} + + +void block_to_hts(u32 block, u32 *head, u32 *track, u32 *sector ) +{ + *head = ( block % ( 18 * 2 ) ) /18; + *track = block / ( 18 * 2 ); + *sector = block % 18 + 1; +} + + +void floppy_setupDMA(void) +{ + u32 eflags; + _local_irq_save(eflags); + DisableDma(2); + ClearDmaFF(2); + SetDmaMode(2,DMA_MODE_READ); + SetDmaAddr(2,(unsigned long)floppy_buffer); + SetDmaCount(2,512); + EnableDma(2); + _local_irq_restore(eflags); +} + + +void floppy_read_cmd(u32 blk) +{ + u32 head; + u32 track; + u32 sector; + + block_to_hts(blk,&head,&track,§or); + + floppy_motorOn(); + io_delay(); + + floppy_setupDMA(); + io_delay(); + + floppy_setmode(); + io_delay(); + floppy_sendbyte (FD_READ); //send read command + floppy_sendbyte (head*4 + 0); + floppy_sendbyte (track); /* Cylinder */ + floppy_sendbyte (head); /* Head */ + floppy_sendbyte (sector); /* Sector */ + floppy_sendbyte (2); /* 0=128, 1=256, 2=512, 3=1024, ... */ + floppy_sendbyte (18); + //floppy_sendbyte (sector+secs-1); /* Last sector in track:here are sectors count */ + floppy_sendbyte (0x1B); + floppy_sendbyte (0xff); + return; +} + +static struct rt_device devF; +static struct rt_mutex lock; +static struct rt_semaphore sem; + +/* RT-Thread device interface */ + +static rt_err_t rt_floppy_init_internal(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t rt_floppy_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_floppy_close(rt_device_t dev) +{ + return RT_EOK; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_floppy_read(rt_device_t device, rt_off_t position, void *buffer, rt_size_t size) +{ + rt_size_t doSize = size; + + rt_mutex_take(&lock, RT_WAITING_FOREVER); + while(size>0) + { + floppy_read_cmd(position); + + rt_sem_take(&sem, RT_WAITING_FOREVER); /* waiting isr sem forever */ + + floppy_result(); + io_delay(); + + if(ST1 != 0 || ST2 != 0) + { + panic("ST0 %d ST1 %d ST2 %d\n",ST0,ST1,ST2); + } + + rt_memcpy(buffer, floppy_buffer, 512); + + floppy_motorOff(); + io_delay(); + + position += 1; + size -= 1; + } + rt_mutex_release(&lock); + + return doSize; +} + +/* position: block page address, not bytes address + * buffer: + * size : how many blocks + */ +static rt_size_t rt_floppy_write(rt_device_t device, rt_off_t position, const void *buffer, rt_size_t size) +{ + rt_mutex_take(&lock, RT_WAITING_FOREVER); + panic("FIXME:I don't know how!\n"); + rt_mutex_release(&lock); + return size; +} + +static rt_err_t rt_floppy_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) + { + struct rt_device_blk_geometry *geometry; + + geometry = (struct rt_device_blk_geometry *)args; + if (geometry == RT_NULL) return -RT_ERROR; + + geometry->bytes_per_sector = SECTOR_SIZE; + geometry->block_size = SECTOR_SIZE; + + geometry->sector_count = floppy_size / SECTOR_SIZE; + } + + return RT_EOK; +} + +static void rt_floppy_isr(int vector, void* param) +{ + (void)vector; + (void)param; + rt_sem_release(&sem); +} + +void rt_floppy_init(void) +{ + struct rt_device *device; + + rt_mutex_init(&lock,"fdlock", RT_IPC_FLAG_FIFO); + rt_sem_init(&sem, "fdsem", 0, RT_IPC_FLAG_FIFO); + + rt_hw_interrupt_install(FLOPPY_IRQ, rt_floppy_isr, RT_NULL, "floppy"); + rt_hw_interrupt_umask(FLOPPY_IRQ); + + floppy_get_info(); + rt_kprintf("Floppy Inc : %s Floppy Type : %s\n",floppy_inc_name,floppy_type); + + device = &(devF); + + device->type = RT_Device_Class_Block; + device->init = rt_floppy_init_internal; + device->open = rt_floppy_open; + device->close = rt_floppy_close; + device->read = rt_floppy_read; + device->write = rt_floppy_write; + device->control = rt_floppy_control; + device->user_data = NULL; + + rt_device_register(device, "floppy", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + +} diff --git a/bsp/x86/drivers/floppy.h b/bsp/x86/drivers/floppy.h new file mode 100644 index 0000000000..f619508c43 --- /dev/null +++ b/bsp/x86/drivers/floppy.h @@ -0,0 +1,71 @@ +#ifndef _FLOPPY_H +#define _FLOPPY_H + +#define FD_STATUS 0x3f4 // 主状态寄存器端口。 +#define FD_DATA 0x3f5 // 数据端口。 +#define FD_DOR 0x3f2 // 数字输出寄存器(也称为数字控制寄存器)。 +#define FD_DIR 0x3f7 // 数字输入寄存器。 +#define FD_DCR 0x3f7 // 数据传输率控制寄存器。 + +/* 主状态寄存器各比特位的含义 */ + +#define STATUS_BUSYMASK 0x0F // 驱动器忙位(每位对应一个驱动器)。 +#define STATUS_BUSY 0x10 // 软盘控制器忙。 +#define STATUS_DMA 0x20 // 0 - 为DMA 数据传输模式,1 - 为非DMA 模式。 +#define STATUS_DIR 0x40 // 传输方向:0 - CPU .. fdc,1 - 相反。 +#define STATUS_READY 0x80 // 数据寄存器就绪位。 + + +/*状态字节0(ST0)各比特位的含义 */ + +#define ST0_DS 0x03 // 驱动器选择号(发生中断时驱动器号)。 +#define ST0_HA 0x04 // 磁头号。 +#define ST0_NR 0x08 // 磁盘驱动器未准备好。 +#define ST0_ECE 0x10 // 设备检测出错(零磁道校准出错)。 +#define ST0_SE 0x20 // 寻道或重新校正操作执行结束。 +#define ST0_INTR 0xC0 // 中断代码位(中断原因),00 - 命令正常结束; + // 01 - 命令异常结束;10 - 命令无效;11 - FDD 就绪状态改变。 + +/*状态字节1(ST1)各比特位的含义 */ + +#define ST1_MAM 0x01 // 未找到地址标志(ID AM)。 +#define ST1_WP 0x02 // 写保护。 +#define ST1_ND 0x04 // 未找到指定的扇区。 +#define ST1_OR 0x10 // 数据传输超时(DMA 控制器故障)。 +#define ST1_CRC 0x20 // CRC 检验出错。 +#define ST1_EOC 0x80 // 访问超过一个磁道上的最大扇区号。 + +/*状态字节2(ST2)各比特位的含义 */ + +#define ST2_MAM 0x01 // 未找到数据地址标志。 +#define ST2_BC 0x02 // 磁道坏。 +#define ST2_SNS 0x04 // 检索(扫描)条件不满足。 +#define ST2_SEH 0x08 // 检索条件满足。 +#define ST2_WC 0x10 // 磁道(柱面)号不符。 +#define ST2_CRC 0x20 // 数据场CRC 校验错。 +#define ST2_CM 0x40 // 读数据遇到删除标志。 + +/*状态字节3(ST3)各比特位的含义 */ + +#define ST3_HA 0x04 // 磁头号。 +#define ST3_TZ 0x10 // 零磁道信号。 +#define ST3_WP 0x40 // 写保护。 + + +/* 软盘命令码 */ + +#define FD_RECALIBRATE 0x07 // 重新校正(磁头退到零磁道)。 +#define FD_SEEK 0x0F // 磁头寻道。 +#define FD_READ 0xE6 // 读数据(MT 多磁道操作,MFM 格式,跳过删除数据)。 +#define FD_WRITE 0xC5 // 写数据(MT,MFM)。 +#define FD_SENSEI 0x08 // 检测中断状态。 +#define FD_SPECIFY 0x03 // 设定驱动器参数(步进速率、磁头卸载时间等)。 + + +/* DMA 命令 */ +#define DMA_READ 0x46 // DMA 读盘,DMA 方式字(送DMA 端口12,11)。 +#define DMA_WRITE 0x4A + +extern void rt_floppy_init(void); + +#endif diff --git a/bsp/x86/drivers/include/bsp.h b/bsp/x86/drivers/include/bsp.h index 8739e185ad..de7f09955e 100644 --- a/bsp/x86/drivers/include/bsp.h +++ b/bsp/x86/drivers/include/bsp.h @@ -74,7 +74,16 @@ extern "C" { #define INTTIMER0 0 #define INTKEYBOARD 1 #define INTUART0_RX 4 - +#define CLOCK_IRQ 0 +#define KEYBOARD_IRQ 1 +#define CASCADE_IRQ 2 /* cascade enable for 2nd AT controller */ +#define ETHER_IRQ 3 /* default ethernet interrupt vector */ +#define SECONDARY_IRQ 3 /* RS232 interrupt vector for port 2 */ +#define RS232_IRQ 4 /* RS232 interrupt vector for port 1 */ +#define XT_WINI_IRQ 5 /* xt winchester */ +#define FLOPPY_IRQ 6 /* floppy disk */ +#define PRINTER_IRQ 7 +#define AT_WINI_IRQ 14 /* at winchester */ /* I/O Addresses of the two 8259A programmable interrupt controllers */ #define IO_PIC1 0x20 /* Master(IRQs 0-7) */ #define IO_PIC2 0xa0 /* Slave(IRQs 8-15) */ diff --git a/bsp/x86/drivers/include/i386.h b/bsp/x86/drivers/include/i386.h index fe023d754a..68c854932b 100644 --- a/bsp/x86/drivers/include/i386.h +++ b/bsp/x86/drivers/include/i386.h @@ -11,6 +11,18 @@ static __inline unsigned char inb(int port) __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port)); return data; } +static __inline unsigned char inb_p(unsigned short port) +{ + unsigned char _v; + __asm__ __volatile__ ("inb %1, %0\n\t" + // "outb %0,$0x80\n\t" + // "outb %0,$0x80\n\t" + // "outb %0,$0x80\n\t" + "outb %0,$0x80" + :"=a" (_v) + :"d" ((unsigned short) port)); + return _v; +} static __inline unsigned short inw(int port) { @@ -39,11 +51,34 @@ static __inline void outb(int port, unsigned char data) __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port)); } + +static __inline void outb_p(char value, unsigned short port) +{ + __asm__ __volatile__ ("outb %0,%1\n\t" + "outb %0,$0x80" + ::"a" ((char) value),"d" ((unsigned short) port)); +} + static __inline void outw(int port, unsigned short data) { __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port)); } +static __inline unsigned char readcmos(int reg) +{ + outb(0x70,reg); + return (unsigned char) inb(0x71); +} + +#define io_delay() \ + __asm__ __volatile__ ("pushal \n\t"\ + "mov $0x3F6, %dx \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "inb %dx, %al \n\t" \ + "popal") + /* Gate descriptors are slightly different*/ struct Gatedesc { unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment