Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
nix61
rt-thread
提交
eb5ea946
R
rt-thread
项目概览
nix61
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
eb5ea946
编写于
8月 16, 2017
作者:
P
parai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tmp floopy driver save, no test
上级
08d13e03
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
530 addition
and
0 deletion
+530
-0
bsp/x86/drivers/dma.h
bsp/x86/drivers/dma.h
+187
-0
bsp/x86/drivers/floppy.c
bsp/x86/drivers/floppy.c
+234
-0
bsp/x86/drivers/floppy.h
bsp/x86/drivers/floppy.h
+72
-0
bsp/x86/drivers/include/i386.h
bsp/x86/drivers/include/i386.h
+37
-0
未找到文件。
bsp/x86/drivers/dma.h
0 → 100644
浏览文件 @
eb5ea946
#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
bsp/x86/drivers/floppy.c
0 → 100644
浏览文件 @
eb5ea946
#include <rtthread.h>
#include <rthw.h>
#include <bsp.h>
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
;
#include "floppy.h"
#include "dma.h"
#define panic(str) rt_kprintf("panic::" str)
#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
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"
;
break
;
case
0x04
:
// 1.44MB 标准软盘
floppy_type
=
"1.44MB"
;
break
;
case
0x05
:
// 2.88MB
floppy_type
=
"2.88MB"
;
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
,
&
sector
);
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
;
}
void
init_fd
(
void
)
{
floppy_get_info
();
rt_kprintf
(
"Floppy Inc : %s Floppy Type : %s"
,
floppy_inc_name
,
floppy_type
);
}
bsp/x86/drivers/floppy.h
0 → 100644
浏览文件 @
eb5ea946
#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
init_fd
(
void
);
extern
void
fd_handler
(
void
);
#endif
bsp/x86/drivers/include/i386.h
浏览文件 @
eb5ea946
...
...
@@ -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,36 @@ 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
(
reg
,
0x70
);
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
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录