commit
858295fb0d
|
@ -385,6 +385,8 @@ CONFIG_RT_LWIP_USING_PING=y
|
|||
# CONFIG_PKG_USING_AGILE_JSMN is not set
|
||||
# CONFIG_PKG_USING_PDULIB is not set
|
||||
# CONFIG_PKG_USING_BTSTACK is not set
|
||||
# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
|
||||
# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
|
||||
|
||||
#
|
||||
# security packages
|
||||
|
@ -410,6 +412,9 @@ CONFIG_RT_LWIP_USING_PING=y
|
|||
# CONFIG_PKG_USING_STEMWIN is not set
|
||||
# CONFIG_PKG_USING_WAVPLAYER is not set
|
||||
# CONFIG_PKG_USING_TJPGD is not set
|
||||
# CONFIG_PKG_USING_HELIX is not set
|
||||
# CONFIG_PKG_USING_AZUREGUIX is not set
|
||||
# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
|
||||
|
||||
#
|
||||
# tools packages
|
||||
|
@ -424,6 +429,7 @@ CONFIG_RT_LWIP_USING_PING=y
|
|||
# CONFIG_PKG_USING_ADBD is not set
|
||||
# CONFIG_PKG_USING_COREMARK is not set
|
||||
# CONFIG_PKG_USING_DHRYSTONE is not set
|
||||
# CONFIG_PKG_USING_MEMORYPERF is not set
|
||||
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
|
||||
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
|
||||
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
|
||||
|
@ -431,6 +437,10 @@ CONFIG_RT_LWIP_USING_PING=y
|
|||
# CONFIG_PKG_USING_GPS_RMC is not set
|
||||
# CONFIG_PKG_USING_URLENCODE is not set
|
||||
# CONFIG_PKG_USING_UMCN is not set
|
||||
# CONFIG_PKG_USING_LWRB2RTT is not set
|
||||
# CONFIG_PKG_USING_CPU_USAGE is not set
|
||||
# CONFIG_PKG_USING_GBK2UTF8 is not set
|
||||
# CONFIG_PKG_USING_VCONSOLE is not set
|
||||
|
||||
#
|
||||
# system packages
|
||||
|
@ -438,12 +448,9 @@ CONFIG_RT_LWIP_USING_PING=y
|
|||
# CONFIG_PKG_USING_GUIENGINE is not set
|
||||
# CONFIG_PKG_USING_CAIRO is not set
|
||||
# CONFIG_PKG_USING_PIXMAN is not set
|
||||
CONFIG_PKG_USING_LWEXT4=y
|
||||
CONFIG_PKG_LWEXT4_PATH="/packages/system/lwext4"
|
||||
CONFIG_RT_USING_DFS_LWEXT4=y
|
||||
CONFIG_PKG_USING_LWEXT4_LATEST_VERSION=y
|
||||
# CONFIG_PKG_USING_LWEXT4 is not set
|
||||
# CONFIG_PKG_USING_LWEXT4_LATEST_VERSION is not set
|
||||
# CONFIG_PKG_USING_LWEXT4_V100 is not set
|
||||
CONFIG_PKG_LWEXT4_VER="latest"
|
||||
# CONFIG_PKG_USING_PARTITION is not set
|
||||
# CONFIG_PKG_USING_FAL is not set
|
||||
# CONFIG_PKG_USING_FLASHDB is not set
|
||||
|
@ -462,8 +469,18 @@ CONFIG_PKG_LWEXT4_VER="latest"
|
|||
# CONFIG_PKG_USING_RAMDISK is not set
|
||||
# CONFIG_PKG_USING_MININI is not set
|
||||
# CONFIG_PKG_USING_QBOOT is not set
|
||||
|
||||
#
|
||||
# Micrium: Micrium software products porting for RT-Thread
|
||||
#
|
||||
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
|
||||
# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
|
||||
# CONFIG_PKG_USING_UC_CRC is not set
|
||||
# CONFIG_PKG_USING_UC_CLK is not set
|
||||
# CONFIG_PKG_USING_UC_COMMON is not set
|
||||
# CONFIG_PKG_USING_UC_MODBUS is not set
|
||||
# CONFIG_PKG_USING_PPOOL is not set
|
||||
# CONFIG_PKG_USING_OPENAMP is not set
|
||||
|
||||
#
|
||||
# peripheral libraries and drivers
|
||||
|
@ -517,6 +534,13 @@ CONFIG_PKG_LWEXT4_VER="latest"
|
|||
# CONFIG_PKG_USING_LD3320 is not set
|
||||
# CONFIG_PKG_USING_WK2124 is not set
|
||||
# CONFIG_PKG_USING_LY68L6400 is not set
|
||||
# CONFIG_PKG_USING_DM9051 is not set
|
||||
# CONFIG_PKG_USING_SSD1306 is not set
|
||||
# CONFIG_PKG_USING_QKEY is not set
|
||||
# CONFIG_PKG_USING_RS485 is not set
|
||||
# CONFIG_PKG_USING_NES is not set
|
||||
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
|
||||
# CONFIG_PKG_USING_VDEVICE is not set
|
||||
|
||||
#
|
||||
# miscellaneous packages
|
||||
|
@ -526,6 +550,7 @@ CONFIG_PKG_LWEXT4_VER="latest"
|
|||
# CONFIG_PKG_USING_FASTLZ is not set
|
||||
# CONFIG_PKG_USING_MINILZO is not set
|
||||
# CONFIG_PKG_USING_QUICKLZ is not set
|
||||
# CONFIG_PKG_USING_LZMA is not set
|
||||
# CONFIG_PKG_USING_MULTIBUTTON is not set
|
||||
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
|
||||
# CONFIG_PKG_USING_CANFESTIVAL is not set
|
||||
|
@ -546,6 +571,7 @@ CONFIG_PKG_LWEXT4_VER="latest"
|
|||
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
|
||||
# CONFIG_PKG_USING_HELLO is not set
|
||||
# CONFIG_PKG_USING_VI is not set
|
||||
# CONFIG_PKG_USING_KI is not set
|
||||
# CONFIG_PKG_USING_NNOM is not set
|
||||
# CONFIG_PKG_USING_LIBANN is not set
|
||||
# CONFIG_PKG_USING_ELAPACK is not set
|
||||
|
@ -554,8 +580,14 @@ CONFIG_PKG_LWEXT4_VER="latest"
|
|||
# CONFIG_PKG_USING_ULAPACK is not set
|
||||
# CONFIG_PKG_USING_UKAL is not set
|
||||
# CONFIG_PKG_USING_CRCLIB is not set
|
||||
|
||||
#
|
||||
# games: games run on RT-Thread console
|
||||
#
|
||||
# CONFIG_PKG_USING_THREES is not set
|
||||
# CONFIG_PKG_USING_2048 is not set
|
||||
# CONFIG_PKG_USING_SNAKE is not set
|
||||
# CONFIG_PKG_USING_TETRIS is not set
|
||||
# CONFIG_PKG_USING_LWGPS is not set
|
||||
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
|
||||
CONFIG_SOC_LS2K1000=y
|
||||
|
|
|
@ -102,7 +102,7 @@ title TFTPBOOT
|
|||
initrd (wd0,0)/initrd.img
|
||||
```
|
||||
|
||||
其中`tftfp://10.1.1.118/rtthread.elf`中的`10.1.1.118`为tftp服务器的ip地址。
|
||||
其中`tftp://10.1.1.118/rtthread.elf`中的`10.1.1.118`为tftp服务器的ip地址。
|
||||
|
||||
**第三步:**
|
||||
|
||||
|
@ -110,7 +110,25 @@ title TFTPBOOT
|
|||
|
||||
以上三步完成之后,重启系统,就可以省略每次都需要进入pmon的输入命令的麻烦,板子上电后,可以自动从系统TFTP服务器中获取固件,然后启动,大大提高调试代码效率。
|
||||
|
||||
## 5. 支持情况
|
||||
## 5.SATA接口的SSD文件系统支持
|
||||
|
||||
当前已经支持SATA接口的SSD文件系统驱动,需要通过menuconfig
|
||||
|
||||
```
|
||||
RT-Thread online packages --->
|
||||
system packages --->
|
||||
lwext4: an excellent choice of ext2/3/4 filesystem for microcontrollers
|
||||
```
|
||||
|
||||
然后输入下面的命令更新软件包
|
||||
|
||||
```
|
||||
pkgs --update
|
||||
```
|
||||
|
||||
输入`scons`编译代码即可使用SATA接口的SSD文件系统。
|
||||
|
||||
## 6. 支持情况
|
||||
|
||||
| 驱动 | 支持情况 | 备注 |
|
||||
| ------ | ---- | :------: |
|
||||
|
@ -120,8 +138,9 @@ title TFTPBOOT
|
|||
| GMAC | 支持 | 网卡驱动 |
|
||||
| RTC | 支持 | - |
|
||||
| SPI | 支持 | - |
|
||||
| SATA SSD | 支持 | 需要打开lwext4软件包 |
|
||||
|
||||
## 6. 联系人信息
|
||||
## 7. 联系人信息
|
||||
|
||||
维护人:[bernard][4]
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-12-29 bigmagic first version
|
||||
*/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef PKG_USING_LWEXT4
|
||||
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs_file.h>
|
||||
#include <ext4.h>
|
||||
#include <ext4_debug.h>
|
||||
#include <blk_device.h>
|
||||
#include <stdint.h>
|
||||
#include <pci.h>
|
||||
|
||||
#define EXT4_DEBUG_ALL (0xFFFFFFFF)
|
||||
#define EXT4_DEBUG_NO (0)
|
||||
|
||||
int mount_ssd(void)
|
||||
{
|
||||
struct blk_device *blkdev = (struct blk_device *)rt_device_find("dwc_ahsata_blk");
|
||||
|
||||
if(blkdev == RT_NULL)
|
||||
{
|
||||
rt_kprintf("dwc_ahsata_blk not found!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ext4_dmask_set(EXT4_DEBUG_NO);
|
||||
blk_device_init(blkdev);
|
||||
dfs_mount("dwc_ahsata_blk","/","ext",0,(void *)1);
|
||||
dfs_mount("dwc_ahsata_blk","/boot","ext",0,(void *)0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_ENV_EXPORT(mount_ssd);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
|
||||
CPPPATH = [cwd]
|
||||
|
||||
if GetDepend('RT_USING_DFS_ELMFAT') == False:
|
||||
SrcRemove(src, 'dwc_ahsata.c')
|
||||
SrcRemove(src, 'libata.c')
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = ['PKG_USING_LWEXT4'], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
#ifndef _AHCI_H_
|
||||
#define _AHCI_H_
|
||||
|
||||
#define AHCI_PCI_BAR 0x24
|
||||
#define AHCI_MAX_SG 56 /* hardware max is 64K */
|
||||
#define AHCI_CMD_SLOT_SZ 32
|
||||
#define AHCI_MAX_CMD_SLOT 32
|
||||
#define AHCI_RX_FIS_SZ 256
|
||||
#define AHCI_CMD_TBL_HDR 0x80
|
||||
#define AHCI_CMD_TBL_CDB 0x40
|
||||
#define AHCI_CMD_TBL_SZ AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
|
||||
#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \
|
||||
AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ)
|
||||
#define AHCI_CMD_ATAPI (1 << 5)
|
||||
#define AHCI_CMD_WRITE (1 << 6)
|
||||
#define AHCI_CMD_PREFETCH (1 << 7)
|
||||
#define AHCI_CMD_RESET (1 << 8)
|
||||
#define AHCI_CMD_CLR_BUSY (1 << 10)
|
||||
|
||||
#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */
|
||||
|
||||
/* Global controller registers */
|
||||
#define HOST_CAP 0x00 /* host capabilities */
|
||||
#define HOST_CTL 0x04 /* global host control */
|
||||
#define HOST_IRQ_STAT 0x08 /* interrupt status */
|
||||
#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
|
||||
#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */
|
||||
#define HOST_CAP2 0x24 /* host capabilities, extended */
|
||||
|
||||
/* HOST_CTL bits */
|
||||
#define HOST_RESET (1 << 0) /* reset controller; self-clear */
|
||||
#define HOST_IRQ_EN (1 << 1) /* global IRQ enable */
|
||||
#define HOST_AHCI_EN (1 << 31) /* AHCI enabled */
|
||||
|
||||
/* Registers for each SATA port */
|
||||
#define PORT_LST_ADDR 0x00 /* command list DMA addr */
|
||||
#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */
|
||||
#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */
|
||||
#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */
|
||||
#define PORT_IRQ_STAT 0x10 /* interrupt status */
|
||||
#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */
|
||||
#define PORT_CMD 0x18 /* port command */
|
||||
#define PORT_TFDATA 0x20 /* taskfile data */
|
||||
#define PORT_SIG 0x24 /* device TF signature */
|
||||
#define PORT_CMD_ISSUE 0x38 /* command issue */
|
||||
#define PORT_SCR 0x28 /* SATA phy register block */
|
||||
#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */
|
||||
#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */
|
||||
#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
|
||||
#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
|
||||
|
||||
#ifdef CONFIG_SUNXI_AHCI
|
||||
#define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */
|
||||
#endif
|
||||
|
||||
/* PORT_IRQ_{STAT,MASK} bits */
|
||||
#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */
|
||||
#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */
|
||||
#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */
|
||||
#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */
|
||||
#define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */
|
||||
#define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */
|
||||
#define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G */
|
||||
#define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */
|
||||
|
||||
#define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */
|
||||
#define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */
|
||||
#define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */
|
||||
#define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */
|
||||
#define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */
|
||||
#define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */
|
||||
#define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */
|
||||
#define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */
|
||||
#define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */
|
||||
|
||||
#define PORT_IRQ_FATAL PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR
|
||||
|
||||
#define DEF_PORT_IRQ PORT_IRQ_FATAL | PORT_IRQ_PHYRDY | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS
|
||||
|
||||
/* PORT_SCR_STAT bits */
|
||||
#define PORT_SCR_STAT_DET_MASK 0x3
|
||||
#define PORT_SCR_STAT_DET_COMINIT 0x1
|
||||
#define PORT_SCR_STAT_DET_PHYRDY 0x3
|
||||
|
||||
/* PORT_CMD bits */
|
||||
#define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */
|
||||
#define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */
|
||||
#define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */
|
||||
#define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine */
|
||||
#define PORT_CMD_CLO (1 << 3) /* Command list override */
|
||||
#define PORT_CMD_POWER_ON (1 << 2) /* Power up device */
|
||||
#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
|
||||
#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
|
||||
|
||||
#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
|
||||
#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
|
||||
#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */
|
||||
|
||||
#define AHCI_MAX_PORTS 32
|
||||
|
||||
#define ATA_FLAG_SATA (1 << 3)
|
||||
#define ATA_FLAG_NO_LEGACY (1 << 4) /* no legacy mode check */
|
||||
#define ATA_FLAG_MMIO (1 << 6) /* use MMIO, not PIO */
|
||||
#define ATA_FLAG_SATA_RESET (1 << 7) /* (obsolete) use COMRESET */
|
||||
#define ATA_FLAG_PIO_DMA (1 << 8) /* PIO cmds via DMA */
|
||||
#define ATA_FLAG_NO_ATAPI (1 << 11) /* No ATAPI support */
|
||||
|
||||
struct ahci_cmd_hdr
|
||||
{
|
||||
u32 opts;
|
||||
u32 status;
|
||||
u64 tbl_addr;
|
||||
//u32 tbl_addr_hi;
|
||||
u32 reserved[4];
|
||||
};
|
||||
|
||||
struct ahci_sg
|
||||
{
|
||||
u64 addr;
|
||||
//u32 addr_hi;
|
||||
u32 reserved;
|
||||
u32 flags_size;
|
||||
};
|
||||
|
||||
struct ahci_ioports
|
||||
{
|
||||
void __iomem *port_mmio;
|
||||
struct ahci_cmd_hdr *cmd_slot;
|
||||
struct ahci_sg *cmd_tbl_sg;
|
||||
ulong cmd_tbl;
|
||||
u32 rx_fis;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ahci_uc_priv - information about an AHCI controller
|
||||
*
|
||||
* When driver model is used, this is accessible using dev_get_uclass_priv(dev)
|
||||
* where dev is the controller (although at present it sometimes stands alone).
|
||||
*/
|
||||
struct ahci_uc_priv
|
||||
{
|
||||
struct rt_device parent;
|
||||
struct ahci_ioports port[AHCI_MAX_PORTS];
|
||||
u16 *ataid[AHCI_MAX_PORTS];
|
||||
u32 n_ports;
|
||||
u32 hard_port_no;
|
||||
u32 host_flags;
|
||||
u32 host_set_flags;
|
||||
void *mmio_base;
|
||||
u32 pio_mask;
|
||||
u32 udma_mask;
|
||||
u32 flags;
|
||||
u32 cap; /* cache of HOST_CAP register */
|
||||
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
|
||||
u32 link_port_map; /*linkup port map*/
|
||||
};
|
||||
|
||||
struct ahci_ops
|
||||
{
|
||||
/**
|
||||
* reset() - reset the controller
|
||||
*
|
||||
* @dev: Controller to reset
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*reset)(struct rt_device *dev);
|
||||
|
||||
/**
|
||||
* port_status() - get the status of a SATA port
|
||||
*
|
||||
* @dev: Controller to reset
|
||||
* @port: Port number to check (0 for first)
|
||||
* @return 0 if detected, -ENXIO if nothing on port, other -ve on error
|
||||
*/
|
||||
int (*port_status)(struct rt_device *dev, int port);
|
||||
|
||||
/**
|
||||
* scan() - scan SATA ports
|
||||
*
|
||||
* @dev: Controller to scan
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*scan)(struct rt_device *dev);
|
||||
};
|
||||
|
||||
#define ahci_get_ops(dev) ((struct ahci_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* sata_reset() - reset the controller
|
||||
*
|
||||
* @dev: Controller to reset
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int sata_reset(struct rt_device *dev);
|
||||
|
||||
/**
|
||||
* sata_port_status() - get the status of a SATA port
|
||||
*
|
||||
* @dev: Controller to reset
|
||||
* @port: Port number to check (0 for first)
|
||||
* @return 0 if detected, -ENXIO if nothin on port, other -ve on error
|
||||
*/
|
||||
int sata_dm_port_status(struct rt_device *dev, int port);
|
||||
|
||||
/**
|
||||
* sata_scan() - scan SATA ports
|
||||
*
|
||||
* @dev: Controller to scan
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int sata_scan(struct rt_device *dev);
|
||||
|
||||
int ahci_init(void __iomem *base);
|
||||
int ahci_reset(void __iomem *base);
|
||||
|
||||
/**
|
||||
* ahci_init_one_dm() - set up a single AHCI port
|
||||
*
|
||||
* @dev: Controller to init
|
||||
*/
|
||||
int ahci_init_one_dm(struct rt_device *dev);
|
||||
|
||||
/**
|
||||
* ahci_start_ports_dm() - start all AHCI ports for a controller
|
||||
*
|
||||
* @dev: Controller containing ports to start
|
||||
*/
|
||||
int ahci_start_ports_dm(struct rt_device *dev);
|
||||
|
||||
/**
|
||||
* ahci_init_dm() - init AHCI for a controller, finding all ports
|
||||
*
|
||||
* @dev: Device to init
|
||||
*/
|
||||
int ahci_init_dm(struct rt_device *dev, void __iomem *base);
|
||||
|
||||
/**
|
||||
* ahci_bind_scsi() - bind a new SCSI bus as a child
|
||||
*
|
||||
* Note that the SCSI bus device will itself bind block devices
|
||||
*
|
||||
* @ahci_dev: AHCI parent device
|
||||
* @devp: Returns new SCSI bus device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ahci_bind_scsi(struct rt_device *ahci_dev, struct rt_device **devp);
|
||||
|
||||
/**
|
||||
* ahci_probe_scsi() - probe and scan the attached SCSI bus
|
||||
*
|
||||
* Note that the SCSI device will itself bind block devices for any storage
|
||||
* devices it finds.
|
||||
*
|
||||
* @ahci_dev: AHCI parent device
|
||||
* @base: Base address of AHCI port
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ahci_probe_scsi(struct rt_device *ahci_dev, ulong base);
|
||||
|
||||
/**
|
||||
* ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI
|
||||
*
|
||||
* Note that the SCSI device will itself bind block devices for any storage
|
||||
* devices it finds.
|
||||
*
|
||||
* @ahci_dev: AHCI parent device
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int ahci_probe_scsi_pci(struct rt_device *ahci_dev);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui first version
|
||||
*/
|
||||
|
||||
#ifndef __ATA_DEBUG_H__
|
||||
#define __ATA_DEBUG_H__
|
||||
//#define ATA_DEBUG
|
||||
#include <rtthread.h>
|
||||
#ifdef ATA_DEBUG
|
||||
#define debug rt_kprintf
|
||||
#else
|
||||
#define debug(...)
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui first version
|
||||
*/
|
||||
|
||||
#ifndef __ATA_INTERFACE_H__
|
||||
#define __ATA_INTERFACE_H__
|
||||
|
||||
typedef rt_uint8_t u8;
|
||||
typedef rt_uint16_t u16;
|
||||
typedef rt_uint32_t u32;
|
||||
typedef rt_uint64_t u64;
|
||||
typedef rt_uint64_t ulong;
|
||||
|
||||
typedef rt_int8_t s8;
|
||||
typedef rt_int16_t s16;
|
||||
typedef rt_int32_t s32;
|
||||
typedef rt_int64_t s64;
|
||||
|
||||
typedef rt_size_t lbaint_t;
|
||||
|
||||
#define __iomem
|
||||
#define mdelay rt_thread_mdelay
|
||||
#define udelay(...) rt_thread_mdelay(1)
|
||||
|
||||
#define cpu_to_le32
|
||||
#define cpu_to_le16
|
||||
#define le32_to_cpu
|
||||
#define le16_to_cpu
|
||||
|
||||
#define flush_cache(...)
|
||||
#define invalidate_dcache_range(...)
|
||||
|
||||
#define ARCH_DMA_MINALIGN 1024
|
||||
|
||||
#define CONFIG_IS_ENABLED
|
||||
#define AHCI 1
|
||||
|
||||
#define VADDR_TO_PHY(vaddr) (((u64)vaddr) - KSEG0BASE)
|
||||
#define LOW_PHY(vaddr) ((u32)VADDR_TO_PHY(vaddr))
|
||||
#define HIGH_PHY(vaddr) ((u32)((VADDR_TO_PHY(vaddr)) >> 32))
|
||||
|
||||
#define ALIGN_1(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
|
||||
#define ALIGN_DOWN(x, a) ALIGN_1((x) - ((a)-1), (a))
|
||||
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
|
||||
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a)-1)) == 0)
|
||||
|
||||
#define ROUND(a, b) (((a) + (b)-1) & ~((b)-1))
|
||||
|
||||
#define PAD_COUNT(s, pad) (((s)-1) / (pad) + 1)
|
||||
#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
|
||||
#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \
|
||||
char __##name[ROUND(PAD_SIZE((size) * sizeof(type), pad), align) + (align - 1)]; \
|
||||
\
|
||||
type *name = (type *)ALIGN_1((rt_ubase_t)__##name, align)
|
||||
#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
|
||||
ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1)
|
||||
#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \
|
||||
ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)
|
||||
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
|
||||
ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
|
||||
|
||||
static inline u32 readl(void *addr)
|
||||
{
|
||||
return *((u32 *)addr);
|
||||
}
|
||||
|
||||
static inline void writel(u32 data, void *addr)
|
||||
{
|
||||
*((u32 *)addr) = data;
|
||||
}
|
||||
|
||||
static inline int ffs(int word)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (word == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
word &= (-word);
|
||||
|
||||
__asm__("clz %0, %1"
|
||||
: "=r"(r)
|
||||
: "r"(word));
|
||||
return 32 - r;
|
||||
}
|
||||
|
||||
static inline void setbits_le32(u32 *addr, u32 value)
|
||||
{
|
||||
*addr = value;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdef.h>
|
||||
#include <dfs.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs_file.h>
|
||||
#include <ext4.h>
|
||||
#include <ext4_debug.h>
|
||||
#include <blk_device.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static struct blk_device *blkdev;
|
||||
static rt_uint32_t disk_sector_size;
|
||||
|
||||
static int blockdev_open(struct ext4_blockdev *bdev)
|
||||
{
|
||||
int r;
|
||||
uint32_t size;
|
||||
rt_device_t device = (rt_device_t)blkdev;
|
||||
struct rt_device_blk_geometry geometry;
|
||||
|
||||
RT_ASSERT(device);
|
||||
|
||||
r = rt_device_open((rt_device_t)blkdev, RT_DEVICE_OFLAG_RDWR);
|
||||
|
||||
if (r != RT_EOK)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
r = rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
|
||||
|
||||
if (RT_EOK == r)
|
||||
{
|
||||
bdev->part_offset = 0;
|
||||
bdev->part_size = geometry.sector_count * geometry.bytes_per_sector;
|
||||
disk_sector_size = geometry.bytes_per_sector;
|
||||
bdev->bdif->ph_bcnt = bdev->part_size / bdev->bdif->ph_bsize;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int blockdev_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
|
||||
uint32_t blk_cnt)
|
||||
{
|
||||
int result;
|
||||
rt_device_t device = (rt_device_t)blkdev;
|
||||
struct blk_device *blk = (struct blk_device *)device;
|
||||
RT_ASSERT(device);
|
||||
|
||||
result = rt_device_read(device, blk_id * (bdev->bdif->ph_bsize / disk_sector_size),
|
||||
buf, blk_cnt * (bdev->bdif->ph_bsize / disk_sector_size));
|
||||
|
||||
if ((blk_cnt * (bdev->bdif->ph_bsize / disk_sector_size)) == result)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -EIO;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int blockdev_bwrite(struct ext4_blockdev *bdev, const void *buf,
|
||||
uint64_t blk_id, uint32_t blk_cnt)
|
||||
{
|
||||
int result;
|
||||
rt_device_t device = (rt_device_t)blkdev;
|
||||
|
||||
RT_ASSERT(device);
|
||||
|
||||
result = rt_device_write(device, blk_id * (bdev->bdif->ph_bsize / disk_sector_size),
|
||||
buf, blk_cnt * (bdev->bdif->ph_bsize / disk_sector_size));
|
||||
|
||||
if ((blk_cnt * (bdev->bdif->ph_bsize / disk_sector_size)) == result)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -EIO;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int blockdev_close(struct ext4_blockdev *bdev)
|
||||
{
|
||||
return rt_device_close((rt_device_t)blkdev);
|
||||
}
|
||||
|
||||
static int blockdev_lock(struct ext4_blockdev *bdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blockdev_unlock(struct ext4_blockdev *bdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXT4_BLOCKDEV_STATIC_INSTANCE(bdev, 4096, 0, blockdev_open,
|
||||
blockdev_bread, blockdev_bwrite, blockdev_close,
|
||||
blockdev_lock, blockdev_unlock);
|
||||
|
||||
void blk_device_init(struct blk_device *blk_devices)
|
||||
{
|
||||
blkdev = blk_devices;
|
||||
|
||||
if (ext4_mbr_scan(&bdev, &(blkdev->ext4_partition)) != EOK)
|
||||
{
|
||||
rt_kprintf("MBR scan failed!\n");
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui first version
|
||||
*/
|
||||
|
||||
#ifndef __BLK_DEVICE_H__
|
||||
#define __BLK_DEVICE_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <ext4_mbr.h>
|
||||
|
||||
#define DEV_TYPE_UNKNOWN 0xff /* not connected */
|
||||
#define DEV_TYPE_HARDDISK 0x00 /* harddisk */
|
||||
#define DEV_TYPE_TAPE 0x01 /* Tape */
|
||||
#define DEV_TYPE_CDROM 0x05 /* CD-ROM */
|
||||
#define DEV_TYPE_OPDISK 0x07 /* optical disk */
|
||||
|
||||
struct blk_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
struct ahci_uc_priv *ahci_device;
|
||||
|
||||
rt_uint8_t target;
|
||||
rt_uint8_t lun;
|
||||
rt_uint8_t type;
|
||||
|
||||
#ifdef RT_USING_DFS_LWEXT4
|
||||
struct ext4_mbr_bdevs ext4_partition;
|
||||
#endif
|
||||
|
||||
rt_bool_t lba48;
|
||||
rt_uint64_t lba;
|
||||
rt_uint64_t blksz;
|
||||
rt_int32_t log2blksz;
|
||||
|
||||
char product[21];
|
||||
char revision[9];
|
||||
char vendor[41];
|
||||
};
|
||||
|
||||
void blk_device_init(struct blk_device *blk_devices);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __DWC_AHSATA_H__
|
||||
#define __DWC_AHSATA_H__
|
||||
|
||||
#define DWCAHSATA_BASE (0x9000000000000000 | 0x400e0000)
|
||||
|
||||
int dwc_ahsata_bus_reset(struct rt_device *dev);
|
||||
int dwc_ahsata_probe(struct rt_device *dev);
|
||||
int dwc_ahsata_scan(struct rt_device *dev);
|
||||
int dwc_ahsata_port_status(struct rt_device *dev, int port);
|
||||
rt_size_t dwc_ahsata_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
|
||||
rt_size_t dwc_ahsata_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
|
||||
rt_err_t dwc_ahsata_control(rt_device_t dev, int cmd, void *args);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
#ifndef __DWC_AHSATA_PRIV_H__
|
||||
#define __DWC_AHSATA_PRIV_H__
|
||||
|
||||
#define DWC_AHSATA_MAX_CMD_SLOTS 32
|
||||
|
||||
/* Max host controller numbers */
|
||||
#define SATA_HC_MAX_NUM 4
|
||||
/* Max command queue depth per host controller */
|
||||
#define DWC_AHSATA_HC_MAX_CMD 32
|
||||
/* Max port number per host controller */
|
||||
#define SATA_HC_MAX_PORT 16
|
||||
|
||||
/* Generic Host Register */
|
||||
|
||||
/* HBA Capabilities Register */
|
||||
#define SATA_HOST_CAP_S64A 0x80000000
|
||||
#define SATA_HOST_CAP_SNCQ 0x40000000
|
||||
#define SATA_HOST_CAP_SSNTF 0x20000000
|
||||
#define SATA_HOST_CAP_SMPS 0x10000000
|
||||
#define SATA_HOST_CAP_SSS 0x08000000
|
||||
#define SATA_HOST_CAP_SALP 0x04000000
|
||||
#define SATA_HOST_CAP_SAL 0x02000000
|
||||
#define SATA_HOST_CAP_SCLO 0x01000000
|
||||
#define SATA_HOST_CAP_ISS_MASK 0x00f00000
|
||||
#define SATA_HOST_CAP_ISS_OFFSET 20
|
||||
#define SATA_HOST_CAP_SNZO 0x00080000
|
||||
#define SATA_HOST_CAP_SAM 0x00040000
|
||||
#define SATA_HOST_CAP_SPM 0x00020000
|
||||
#define SATA_HOST_CAP_PMD 0x00008000
|
||||
#define SATA_HOST_CAP_SSC 0x00004000
|
||||
#define SATA_HOST_CAP_PSC 0x00002000
|
||||
#define SATA_HOST_CAP_NCS 0x00001f00
|
||||
#define SATA_HOST_CAP_CCCS 0x00000080
|
||||
#define SATA_HOST_CAP_EMS 0x00000040
|
||||
#define SATA_HOST_CAP_SXS 0x00000020
|
||||
#define SATA_HOST_CAP_NP_MASK 0x0000001f
|
||||
|
||||
/* Global HBA Control Register */
|
||||
#define SATA_HOST_GHC_AE 0x80000000
|
||||
#define SATA_HOST_GHC_IE 0x00000002
|
||||
#define SATA_HOST_GHC_HR 0x00000001
|
||||
|
||||
/* Interrupt Status Register */
|
||||
|
||||
/* Ports Implemented Register */
|
||||
|
||||
/* AHCI Version Register */
|
||||
#define SATA_HOST_VS_MJR_MASK 0xffff0000
|
||||
#define SATA_HOST_VS_MJR_OFFSET 16
|
||||
#define SATA_HOST_VS_MJR_MNR 0x0000ffff
|
||||
|
||||
/* Command Completion Coalescing Control */
|
||||
#define SATA_HOST_CCC_CTL_TV_MASK 0xffff0000
|
||||
#define SATA_HOST_CCC_CTL_TV_OFFSET 16
|
||||
#define SATA_HOST_CCC_CTL_CC_MASK 0x0000ff00
|
||||
#define SATA_HOST_CCC_CTL_CC_OFFSET 8
|
||||
#define SATA_HOST_CCC_CTL_INT_MASK 0x000000f8
|
||||
#define SATA_HOST_CCC_CTL_INT_OFFSET 3
|
||||
#define SATA_HOST_CCC_CTL_EN 0x00000001
|
||||
|
||||
/* Command Completion Coalescing Ports */
|
||||
|
||||
/* HBA Capabilities Extended Register */
|
||||
#define SATA_HOST_CAP2_APST 0x00000004
|
||||
|
||||
/* BIST Activate FIS Register */
|
||||
#define SATA_HOST_BISTAFR_NCP_MASK 0x0000ff00
|
||||
#define SATA_HOST_BISTAFR_NCP_OFFSET 8
|
||||
#define SATA_HOST_BISTAFR_PD_MASK 0x000000ff
|
||||
#define SATA_HOST_BISTAFR_PD_OFFSET 0
|
||||
|
||||
/* BIST Control Register */
|
||||
#define SATA_HOST_BISTCR_FERLB 0x00100000
|
||||
#define SATA_HOST_BISTCR_TXO 0x00040000
|
||||
#define SATA_HOST_BISTCR_CNTCLR 0x00020000
|
||||
#define SATA_HOST_BISTCR_NEALB 0x00010000
|
||||
#define SATA_HOST_BISTCR_LLC_MASK 0x00000700
|
||||
#define SATA_HOST_BISTCR_LLC_OFFSET 8
|
||||
#define SATA_HOST_BISTCR_ERREN 0x00000040
|
||||
#define SATA_HOST_BISTCR_FLIP 0x00000020
|
||||
#define SATA_HOST_BISTCR_PV 0x00000010
|
||||
#define SATA_HOST_BISTCR_PATTERN_MASK 0x0000000f
|
||||
#define SATA_HOST_BISTCR_PATTERN_OFFSET 0
|
||||
|
||||
/* BIST FIS Count Register */
|
||||
|
||||
/* BIST Status Register */
|
||||
#define SATA_HOST_BISTSR_FRAMERR_MASK 0x0000ffff
|
||||
#define SATA_HOST_BISTSR_FRAMERR_OFFSET 0
|
||||
#define SATA_HOST_BISTSR_BRSTERR_MASK 0x00ff0000
|
||||
#define SATA_HOST_BISTSR_BRSTERR_OFFSET 16
|
||||
|
||||
/* BIST DWORD Error Count Register */
|
||||
|
||||
/* OOB Register*/
|
||||
#define SATA_HOST_OOBR_WE 0x80000000
|
||||
#define SATA_HOST_OOBR_cwMin_MASK 0x7f000000
|
||||
#define SATA_HOST_OOBR_cwMAX_MASK 0x00ff0000
|
||||
#define SATA_HOST_OOBR_ciMin_MASK 0x0000ff00
|
||||
#define SATA_HOST_OOBR_ciMax_MASK 0x000000ff
|
||||
|
||||
/* Timer 1-ms Register */
|
||||
|
||||
/* Global Parameter 1 Register */
|
||||
#define SATA_HOST_GPARAM1R_ALIGN_M 0x80000000
|
||||
#define SATA_HOST_GPARAM1R_RX_BUFFER 0x40000000
|
||||
#define SATA_HOST_GPARAM1R_PHY_DATA_MASK 0x30000000
|
||||
#define SATA_HOST_GPARAM1R_PHY_RST 0x08000000
|
||||
#define SATA_HOST_GPARAM1R_PHY_CTRL_MASK 0x07e00000
|
||||
#define SATA_HOST_GPARAM1R_PHY_STAT_MASK 0x001f8000
|
||||
#define SATA_HOST_GPARAM1R_LATCH_M 0x00004000
|
||||
#define SATA_HOST_GPARAM1R_BIST_M 0x00002000
|
||||
#define SATA_HOST_GPARAM1R_PHY_TYPE 0x00001000
|
||||
#define SATA_HOST_GPARAM1R_RETURN_ERR 0x00000400
|
||||
#define SATA_HOST_GPARAM1R_AHB_ENDIAN_MASK 0x00000300
|
||||
#define SATA_HOST_GPARAM1R_S_HADDR 0X00000080
|
||||
#define SATA_HOST_GPARAM1R_M_HADDR 0X00000040
|
||||
|
||||
/* Global Parameter 2 Register */
|
||||
#define SATA_HOST_GPARAM2R_DEV_CP 0x00004000
|
||||
#define SATA_HOST_GPARAM2R_DEV_MP 0x00002000
|
||||
#define SATA_HOST_GPARAM2R_DEV_ENCODE_M 0x00001000
|
||||
#define SATA_HOST_GPARAM2R_RXOOB_CLK_M 0x00000800
|
||||
#define SATA_HOST_GPARAM2R_RXOOB_M 0x00000400
|
||||
#define SATA_HOST_GPARAM2R_TX_OOB_M 0x00000200
|
||||
#define SATA_HOST_GPARAM2R_RXOOB_CLK_MASK 0x000001ff
|
||||
|
||||
/* Port Parameter Register */
|
||||
#define SATA_HOST_PPARAMR_TX_MEM_M 0x00000200
|
||||
#define SATA_HOST_PPARAMR_TX_MEM_S 0x00000100
|
||||
#define SATA_HOST_PPARAMR_RX_MEM_M 0x00000080
|
||||
#define SATA_HOST_PPARAMR_RX_MEM_S 0x00000040
|
||||
#define SATA_HOST_PPARAMR_TXFIFO_DEPTH_MASK 0x00000038
|
||||
#define SATA_HOST_PPARAMR_RXFIFO_DEPTH_MASK 0x00000007
|
||||
|
||||
/* Test Register */
|
||||
#define SATA_HOST_TESTR_PSEL_MASK 0x00070000
|
||||
#define SATA_HOST_TESTR_TEST_IF 0x00000001
|
||||
|
||||
/* Port Register Descriptions */
|
||||
/* Port# Command List Base Address Register */
|
||||
#define SATA_PORT_CLB_CLB_MASK 0xfffffc00
|
||||
|
||||
/* Port# Command List Base Address Upper 32-Bits Register */
|
||||
|
||||
/* Port# FIS Base Address Register */
|
||||
#define SATA_PORT_FB_FB_MASK 0xfffffff0
|
||||
|
||||
/* Port# FIS Base Address Upper 32-Bits Register */
|
||||
|
||||
/* Port# Interrupt Status Register */
|
||||
#define SATA_PORT_IS_CPDS 0x80000000
|
||||
#define SATA_PORT_IS_TFES 0x40000000
|
||||
#define SATA_PORT_IS_HBFS 0x20000000
|
||||
#define SATA_PORT_IS_HBDS 0x10000000
|
||||
#define SATA_PORT_IS_IFS 0x08000000
|
||||
#define SATA_PORT_IS_INFS 0x04000000
|
||||
#define SATA_PORT_IS_OFS 0x01000000
|
||||
#define SATA_PORT_IS_IPMS 0x00800000
|
||||
#define SATA_PORT_IS_PRCS 0x00400000
|
||||
#define SATA_PORT_IS_DMPS 0x00000080
|
||||
#define SATA_PORT_IS_PCS 0x00000040
|
||||
#define SATA_PORT_IS_DPS 0x00000020
|
||||
#define SATA_PORT_IS_UFS 0x00000010
|
||||
#define SATA_PORT_IS_SDBS 0x00000008
|
||||
#define SATA_PORT_IS_DSS 0x00000004
|
||||
#define SATA_PORT_IS_PSS 0x00000002
|
||||
#define SATA_PORT_IS_DHRS 0x00000001
|
||||
|
||||
/* Port# Interrupt Enable Register */
|
||||
#define SATA_PORT_IE_CPDE 0x80000000
|
||||
#define SATA_PORT_IE_TFEE 0x40000000
|
||||
#define SATA_PORT_IE_HBFE 0x20000000
|
||||
#define SATA_PORT_IE_HBDE 0x10000000
|
||||
#define SATA_PORT_IE_IFE 0x08000000
|
||||
#define SATA_PORT_IE_INFE 0x04000000
|
||||
#define SATA_PORT_IE_OFE 0x01000000
|
||||
#define SATA_PORT_IE_IPME 0x00800000
|
||||
#define SATA_PORT_IE_PRCE 0x00400000
|
||||
#define SATA_PORT_IE_DMPE 0x00000080
|
||||
#define SATA_PORT_IE_PCE 0x00000040
|
||||
#define SATA_PORT_IE_DPE 0x00000020
|
||||
#define SATA_PORT_IE_UFE 0x00000010
|
||||
#define SATA_PORT_IE_SDBE 0x00000008
|
||||
#define SATA_PORT_IE_DSE 0x00000004
|
||||
#define SATA_PORT_IE_PSE 0x00000002
|
||||
#define SATA_PORT_IE_DHRE 0x00000001
|
||||
|
||||
/* Port# Command Register */
|
||||
#define SATA_PORT_CMD_ICC_MASK 0xf0000000
|
||||
#define SATA_PORT_CMD_ASP 0x08000000
|
||||
#define SATA_PORT_CMD_ALPE 0x04000000
|
||||
#define SATA_PORT_CMD_DLAE 0x02000000
|
||||
#define SATA_PORT_CMD_ATAPI 0x01000000
|
||||
#define SATA_PORT_CMD_APSTE 0x00800000
|
||||
#define SATA_PORT_CMD_ESP 0x00200000
|
||||
#define SATA_PORT_CMD_CPD 0x00100000
|
||||
#define SATA_PORT_CMD_MPSP 0x00080000
|
||||
#define SATA_PORT_CMD_HPCP 0x00040000
|
||||
#define SATA_PORT_CMD_PMA 0x00020000
|
||||
#define SATA_PORT_CMD_CPS 0x00010000
|
||||
#define SATA_PORT_CMD_CR 0x00008000
|
||||
#define SATA_PORT_CMD_FR 0x00004000
|
||||
#define SATA_PORT_CMD_MPSS 0x00002000
|
||||
#define SATA_PORT_CMD_CCS_MASK 0x00001f00
|
||||
#define SATA_PORT_CMD_FRE 0x00000010
|
||||
#define SATA_PORT_CMD_CLO 0x00000008
|
||||
#define SATA_PORT_CMD_POD 0x00000004
|
||||
#define SATA_PORT_CMD_SUD 0x00000002
|
||||
#define SATA_PORT_CMD_ST 0x00000001
|
||||
|
||||
/* Port# Task File Data Register */
|
||||
#define SATA_PORT_TFD_ERR_MASK 0x0000ff00
|
||||
#define SATA_PORT_TFD_STS_MASK 0x000000ff
|
||||
#define SATA_PORT_TFD_STS_ERR 0x00000001
|
||||
#define SATA_PORT_TFD_STS_DRQ 0x00000008
|
||||
#define SATA_PORT_TFD_STS_BSY 0x00000080
|
||||
|
||||
/* Port# Signature Register */
|
||||
|
||||
/* Port# Serial ATA Status {SStatus} Register */
|
||||
#define SATA_PORT_SSTS_IPM_MASK 0x00000f00
|
||||
#define SATA_PORT_SSTS_SPD_MASK 0x000000f0
|
||||
#define SATA_PORT_SSTS_DET_MASK 0x0000000f
|
||||
|
||||
/* Port# Serial ATA Control {SControl} Register */
|
||||
#define SATA_PORT_SCTL_IPM_MASK 0x00000f00
|
||||
#define SATA_PORT_SCTL_SPD_MASK 0x000000f0
|
||||
#define SATA_PORT_SCTL_DET_MASK 0x0000000f
|
||||
|
||||
/* Port# Serial ATA Error {SError} Register */
|
||||
#define SATA_PORT_SERR_DIAG_X 0x04000000
|
||||
#define SATA_PORT_SERR_DIAG_F 0x02000000
|
||||
#define SATA_PORT_SERR_DIAG_T 0x01000000
|
||||
#define SATA_PORT_SERR_DIAG_S 0x00800000
|
||||
#define SATA_PORT_SERR_DIAG_H 0x00400000
|
||||
#define SATA_PORT_SERR_DIAG_C 0x00200000
|
||||
#define SATA_PORT_SERR_DIAG_D 0x00100000
|
||||
#define SATA_PORT_SERR_DIAG_B 0x00080000
|
||||
#define SATA_PORT_SERR_DIAG_W 0x00040000
|
||||
#define SATA_PORT_SERR_DIAG_I 0x00020000
|
||||
#define SATA_PORT_SERR_DIAG_N 0x00010000
|
||||
#define SATA_PORT_SERR_ERR_E 0x00000800
|
||||
#define SATA_PORT_SERR_ERR_P 0x00000400
|
||||
#define SATA_PORT_SERR_ERR_C 0x00000200
|
||||
#define SATA_PORT_SERR_ERR_T 0x00000100
|
||||
#define SATA_PORT_SERR_ERR_M 0x00000002
|
||||
#define SATA_PORT_SERR_ERR_I 0x00000001
|
||||
|
||||
/* Port# Serial ATA Active {SActive} Register */
|
||||
|
||||
/* Port# Command Issue Register */
|
||||
|
||||
/* Port# Serial ATA Notification Register */
|
||||
|
||||
/* Port# DMA Control Register */
|
||||
#define SATA_PORT_DMACR_RXABL_MASK 0x0000f000
|
||||
#define SATA_PORT_DMACR_TXABL_MASK 0x00000f00
|
||||
#define SATA_PORT_DMACR_RXTS_MASK 0x000000f0
|
||||
#define SATA_PORT_DMACR_TXTS_MASK 0x0000000f
|
||||
|
||||
/* Port# PHY Control Register */
|
||||
|
||||
/* Port# PHY Status Register */
|
||||
|
||||
#define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry)
|
||||
|
||||
/* DW0
|
||||
*/
|
||||
#define CMD_HDR_DI_CFL_MASK 0x0000001f
|
||||
#define CMD_HDR_DI_CFL_OFFSET 0
|
||||
#define CMD_HDR_DI_A 0x00000020
|
||||
#define CMD_HDR_DI_W 0x00000040
|
||||
#define CMD_HDR_DI_P 0x00000080
|
||||
#define CMD_HDR_DI_R 0x00000100
|
||||
#define CMD_HDR_DI_B 0x00000200
|
||||
#define CMD_HDR_DI_C 0x00000400
|
||||
#define CMD_HDR_DI_PMP_MASK 0x0000f000
|
||||
#define CMD_HDR_DI_PMP_OFFSET 12
|
||||
#define CMD_HDR_DI_PRDTL 0xffff0000
|
||||
#define CMD_HDR_DI_PRDTL_OFFSET 16
|
||||
|
||||
/* prde_fis_len
|
||||
*/
|
||||
#define CMD_HDR_PRD_ENTRY_SHIFT 16
|
||||
#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
|
||||
#define CMD_HDR_FIS_LEN_SHIFT 2
|
||||
|
||||
/* attribute
|
||||
*/
|
||||
#define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */
|
||||
#define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */
|
||||
/* Snoop enable for all descriptor */
|
||||
#define CMD_HDR_ATTR_SNOOP 0x00000200
|
||||
#define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */
|
||||
#define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */
|
||||
/* BIST - require the host to enter BIST mode */
|
||||
#define CMD_HDR_ATTR_BIST 0x00000040
|
||||
#define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */
|
||||
#define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */
|
||||
|
||||
#define FLAGS_DMA 0x00000000
|
||||
#define FLAGS_FPDMA 0x00000001
|
||||
|
||||
#define SATA_FLAG_Q_DEP_MASK 0x0000000f
|
||||
#define SATA_FLAG_WCACHE 0x00000100
|
||||
#define SATA_FLAG_FLUSH 0x00000200
|
||||
#define SATA_FLAG_FLUSH_EXT 0x00000400
|
||||
|
||||
#define READ_CMD 0
|
||||
#define WRITE_CMD 1
|
||||
|
||||
#endif /* __DWC_AHSATA_H__ */
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
#ifndef __FIS_H__
|
||||
#define __FIS_H__
|
||||
/*
|
||||
* Register - Host to Device FIS
|
||||
*/
|
||||
typedef struct sata_fis_h2d
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port_c;
|
||||
u8 command;
|
||||
u8 features;
|
||||
u8 lba_low;
|
||||
u8 lba_mid;
|
||||
u8 lba_high;
|
||||
u8 device;
|
||||
u8 lba_low_exp;
|
||||
u8 lba_mid_exp;
|
||||
u8 lba_high_exp;
|
||||
u8 features_exp;
|
||||
u8 sector_count;
|
||||
u8 sector_count_exp;
|
||||
u8 res1;
|
||||
u8 control;
|
||||
u8 res2[4];
|
||||
} __attribute__((packed)) sata_fis_h2d_t;
|
||||
|
||||
/*
|
||||
* Register - Host to Device FIS for read/write FPDMA queued
|
||||
*/
|
||||
typedef struct sata_fis_h2d_ncq
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port_c;
|
||||
u8 command;
|
||||
u8 sector_count_low;
|
||||
u8 lba_low;
|
||||
u8 lba_mid;
|
||||
u8 lba_high;
|
||||
u8 device;
|
||||
u8 lba_low_exp;
|
||||
u8 lba_mid_exp;
|
||||
u8 lba_high_exp;
|
||||
u8 sector_count_high;
|
||||
u8 tag;
|
||||
u8 res1;
|
||||
u8 res2;
|
||||
u8 control;
|
||||
u8 res3[4];
|
||||
} __attribute__((packed)) sata_fis_h2d_ncq_t;
|
||||
|
||||
/*
|
||||
* Register - Device to Host FIS
|
||||
*/
|
||||
typedef struct sata_fis_d2h
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port_i;
|
||||
u8 status;
|
||||
u8 error;
|
||||
u8 lba_low;
|
||||
u8 lba_mid;
|
||||
u8 lba_high;
|
||||
u8 device;
|
||||
u8 lba_low_exp;
|
||||
u8 lba_mid_exp;
|
||||
u8 lba_high_exp;
|
||||
u8 res1;
|
||||
u8 sector_count;
|
||||
u8 sector_count_exp;
|
||||
u8 res2[2];
|
||||
u8 res3[4];
|
||||
} __attribute__((packed)) sata_fis_d2h_t;
|
||||
|
||||
/*
|
||||
* DMA Setup - Device to Host or Host to Device FIS
|
||||
*/
|
||||
typedef struct sata_fis_dma_setup
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port_dir_int_act;
|
||||
u8 res1;
|
||||
u8 res2;
|
||||
u32 dma_buffer_id_low;
|
||||
u32 dma_buffer_id_high;
|
||||
u32 res3;
|
||||
u32 dma_buffer_offset;
|
||||
u32 dma_transfer_count;
|
||||
u32 res4;
|
||||
} __attribute__((packed)) sata_fis_dma_setup_t;
|
||||
|
||||
/*
|
||||
* PIO Setup - Device to Host FIS
|
||||
*/
|
||||
typedef struct sata_fis_pio_setup
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port_dir_int;
|
||||
u8 status;
|
||||
u8 error;
|
||||
u8 lba_low;
|
||||
u8 lba_mid;
|
||||
u8 lba_high;
|
||||
u8 res1;
|
||||
u8 lba_low_exp;
|
||||
u8 lba_mid_exp;
|
||||
u8 lba_high_exp;
|
||||
u8 res2;
|
||||
u8 sector_count;
|
||||
u8 sector_count_exp;
|
||||
u8 res3;
|
||||
u8 e_status;
|
||||
u16 transfer_count;
|
||||
u16 res4;
|
||||
} __attribute__((packed)) sata_fis_pio_setup_t;
|
||||
|
||||
/*
|
||||
* Data - Host to Device or Device to Host FIS
|
||||
*/
|
||||
typedef struct sata_fis_data
|
||||
{
|
||||
u8 fis_type;
|
||||
u8 pm_port;
|
||||
u8 res1;
|
||||
u8 res2;
|
||||
u32 data[2048];
|
||||
} __attribute__((packed)) sata_fis_data_t;
|
||||
|
||||
/* fis_type - SATA FIS type
|
||||
*/
|
||||
enum sata_fis_type
|
||||
{
|
||||
SATA_FIS_TYPE_REGISTER_H2D = 0x27,
|
||||
SATA_FIS_TYPE_REGISTER_D2H = 0x34,
|
||||
SATA_FIS_TYPE_DMA_ACT_D2H = 0x39,
|
||||
SATA_FIS_TYPE_DMA_SETUP_BI = 0x41,
|
||||
SATA_FIS_TYPE_DATA_BI = 0x46,
|
||||
SATA_FIS_TYPE_BIST_ACT_BI = 0x58,
|
||||
SATA_FIS_TYPE_PIO_SETUP_D2H = 0x5F,
|
||||
SATA_FIS_TYPE_SET_DEVICE_BITS_D2H = 0xA1,
|
||||
};
|
||||
|
||||
#endif /* __FIS_H__ */
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <ata_interface.h>
|
||||
#include <libata.h>
|
||||
|
||||
u64 ata_id_n_sectors(u16 *id)
|
||||
{
|
||||
if (ata_id_has_lba(id)) {
|
||||
if (ata_id_has_lba48(id))
|
||||
return ata_id_u64(id, ATA_ID_LBA48_SECTORS);
|
||||
else
|
||||
return ata_id_u32(id, ATA_ID_LBA_SECTORS);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 ata_dev_classify(u32 sig)
|
||||
{
|
||||
u8 lbam, lbah;
|
||||
|
||||
lbam = (sig >> 16) & 0xff;
|
||||
lbah = (sig >> 24) & 0xff;
|
||||
|
||||
if (((lbam == 0) && (lbah == 0)) ||
|
||||
((lbam == 0x3c) && (lbah == 0xc3)))
|
||||
return ATA_DEV_ATA;
|
||||
|
||||
if ((lbam == 0x14) && (lbah == 0xeb))
|
||||
return ATA_DEV_ATAPI;
|
||||
|
||||
if ((lbam == 0x69) && (lbah == 0x96))
|
||||
return ATA_DEV_PMP;
|
||||
|
||||
return ATA_DEV_UNKNOWN;
|
||||
}
|
||||
|
||||
static void ata_id_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len)
|
||||
{
|
||||
unsigned int c;
|
||||
|
||||
while (len > 0) {
|
||||
c = id[ofs] >> 8;
|
||||
*s = c;
|
||||
s++;
|
||||
|
||||
c = id[ofs] & 0xff;
|
||||
*s = c;
|
||||
s++;
|
||||
|
||||
ofs++;
|
||||
len -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
void ata_id_c_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
ata_id_string(id, s, ofs, len - 1);
|
||||
|
||||
p = s + strnlen((char *)s, len - 1);
|
||||
while (p > s && p[-1] == ' ')
|
||||
p--;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
void ata_dump_id(u16 *id)
|
||||
{
|
||||
unsigned char serial[ATA_ID_SERNO_LEN + 1];
|
||||
unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
|
||||
unsigned char product[ATA_ID_PROD_LEN + 1];
|
||||
u64 n_sectors;
|
||||
|
||||
/* Serial number */
|
||||
ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
|
||||
printf("S/N: %s\n\r", serial);
|
||||
|
||||
/* Firmware version */
|
||||
ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
|
||||
printf("Firmware version: %s\n\r", firmware);
|
||||
|
||||
/* Product model */
|
||||
ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
|
||||
printf("Product model number: %s\n\r", product);
|
||||
|
||||
/* Total sectors of device */
|
||||
n_sectors = ata_id_n_sectors(id);
|
||||
printf("Capablity: %lld sectors\n\r", n_sectors);
|
||||
|
||||
printf ("id[49]: capabilities = 0x%04x\n"
|
||||
"id[53]: field valid = 0x%04x\n"
|
||||
"id[63]: mwdma = 0x%04x\n"
|
||||
"id[64]: pio = 0x%04x\n"
|
||||
"id[75]: queue depth = 0x%04x\n",
|
||||
id[49],
|
||||
id[53],
|
||||
id[63],
|
||||
id[64],
|
||||
id[75]);
|
||||
|
||||
printf ("id[76]: sata capablity = 0x%04x\n"
|
||||
"id[78]: sata features supported = 0x%04x\n"
|
||||
"id[79]: sata features enable = 0x%04x\n",
|
||||
id[76],
|
||||
id[78],
|
||||
id[79]);
|
||||
|
||||
printf ("id[80]: major version = 0x%04x\n"
|
||||
"id[81]: minor version = 0x%04x\n"
|
||||
"id[82]: command set supported 1 = 0x%04x\n"
|
||||
"id[83]: command set supported 2 = 0x%04x\n"
|
||||
"id[84]: command set extension = 0x%04x\n",
|
||||
id[80],
|
||||
id[81],
|
||||
id[82],
|
||||
id[83],
|
||||
id[84]);
|
||||
printf ("id[85]: command set enable 1 = 0x%04x\n"
|
||||
"id[86]: command set enable 2 = 0x%04x\n"
|
||||
"id[87]: command set default = 0x%04x\n"
|
||||
"id[88]: udma = 0x%04x\n"
|
||||
"id[93]: hardware reset result = 0x%04x\n",
|
||||
id[85],
|
||||
id[86],
|
||||
id[87],
|
||||
id[88],
|
||||
id[93]);
|
||||
}
|
||||
|
||||
void ata_swap_buf_le16(u16 *buf, unsigned int buf_words)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < buf_words; i++)
|
||||
{
|
||||
buf[i] = le16_to_cpu(buf[i]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,653 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-08-19 lizhirui porting to ls2k
|
||||
*/
|
||||
|
||||
#ifndef __LIBATA_H__
|
||||
#define __LIBATA_H__
|
||||
|
||||
enum {
|
||||
/* various global constants */
|
||||
ATA_MAX_DEVICES = 2, /* per bus/port */
|
||||
ATA_MAX_PRD = 256, /* we could make these 256/256 */
|
||||
ATA_SECT_SIZE = 512,
|
||||
ATA_MAX_SECTORS_128 = 128,
|
||||
ATA_MAX_SECTORS = 256,
|
||||
ATA_MAX_SECTORS_LBA48 = 65535,
|
||||
ATA_MAX_SECTORS_TAPE = 65535,
|
||||
|
||||
ATA_ID_WORDS = 256,
|
||||
ATA_ID_SERNO = 10,
|
||||
ATA_ID_FW_REV = 23,
|
||||
ATA_ID_PROD = 27,
|
||||
ATA_ID_OLD_PIO_MODES = 51,
|
||||
ATA_ID_FIELD_VALID = 53,
|
||||
ATA_ID_LBA_SECTORS = 60,
|
||||
ATA_ID_MWDMA_MODES = 63,
|
||||
ATA_ID_PIO_MODES = 64,
|
||||
ATA_ID_EIDE_DMA_MIN = 65,
|
||||
ATA_ID_EIDE_PIO = 67,
|
||||
ATA_ID_EIDE_PIO_IORDY = 68,
|
||||
ATA_ID_PIO4 = (1 << 1),
|
||||
ATA_ID_QUEUE_DEPTH = 75,
|
||||
ATA_ID_SATA_CAP = 76,
|
||||
ATA_ID_SATA_FEATURES = 78,
|
||||
ATA_ID_SATA_FEATURES_EN = 79,
|
||||
ATA_ID_MAJOR_VER = 80,
|
||||
ATA_ID_MINOR_VER = 81,
|
||||
ATA_ID_UDMA_MODES = 88,
|
||||
ATA_ID_LBA48_SECTORS = 100,
|
||||
|
||||
ATA_ID_SERNO_LEN = 20,
|
||||
ATA_ID_FW_REV_LEN = 8,
|
||||
ATA_ID_PROD_LEN = 40,
|
||||
|
||||
ATA_PCI_CTL_OFS = 2,
|
||||
|
||||
ATA_PIO0 = (1 << 0),
|
||||
ATA_PIO1 = ATA_PIO0 | (1 << 1),
|
||||
ATA_PIO2 = ATA_PIO1 | (1 << 2),
|
||||
ATA_PIO3 = ATA_PIO2 | (1 << 3),
|
||||
ATA_PIO4 = ATA_PIO3 | (1 << 4),
|
||||
ATA_PIO5 = ATA_PIO4 | (1 << 5),
|
||||
ATA_PIO6 = ATA_PIO5 | (1 << 6),
|
||||
|
||||
ATA_SWDMA0 = (1 << 0),
|
||||
ATA_SWDMA1 = ATA_SWDMA0 | (1 << 1),
|
||||
ATA_SWDMA2 = ATA_SWDMA1 | (1 << 2),
|
||||
|
||||
ATA_SWDMA2_ONLY = (1 << 2),
|
||||
|
||||
ATA_MWDMA0 = (1 << 0),
|
||||
ATA_MWDMA1 = ATA_MWDMA0 | (1 << 1),
|
||||
ATA_MWDMA2 = ATA_MWDMA1 | (1 << 2),
|
||||
|
||||
ATA_MWDMA12_ONLY = (1 << 1) | (1 << 2),
|
||||
ATA_MWDMA2_ONLY = (1 << 2),
|
||||
|
||||
ATA_UDMA0 = (1 << 0),
|
||||
ATA_UDMA1 = ATA_UDMA0 | (1 << 1),
|
||||
ATA_UDMA2 = ATA_UDMA1 | (1 << 2),
|
||||
ATA_UDMA3 = ATA_UDMA2 | (1 << 3),
|
||||
ATA_UDMA4 = ATA_UDMA3 | (1 << 4),
|
||||
ATA_UDMA5 = ATA_UDMA4 | (1 << 5),
|
||||
ATA_UDMA6 = ATA_UDMA5 | (1 << 6),
|
||||
ATA_UDMA7 = ATA_UDMA6 | (1 << 7),
|
||||
/* ATA_UDMA7 is just for completeness... doesn't exist (yet?). */
|
||||
|
||||
ATA_UDMA_MASK_40C = ATA_UDMA2, /* udma0-2 */
|
||||
|
||||
/* DMA-related */
|
||||
ATA_PRD_SZ = 8,
|
||||
ATA_PRD_TBL_SZ = (ATA_MAX_PRD * ATA_PRD_SZ),
|
||||
ATA_PRD_EOT = (1 << 31), /* end-of-table flag */
|
||||
|
||||
ATA_DMA_TABLE_OFS = 4,
|
||||
ATA_DMA_STATUS = 2,
|
||||
ATA_DMA_CMD = 0,
|
||||
ATA_DMA_WR = (1 << 3),
|
||||
ATA_DMA_START = (1 << 0),
|
||||
ATA_DMA_INTR = (1 << 2),
|
||||
ATA_DMA_ERR = (1 << 1),
|
||||
ATA_DMA_ACTIVE = (1 << 0),
|
||||
|
||||
/* bits in ATA command block registers */
|
||||
ATA_HOB = (1 << 7), /* LBA48 selector */
|
||||
ATA_NIEN = (1 << 1), /* disable-irq flag */
|
||||
ATA_LBA = (1 << 6), /* LBA28 selector */
|
||||
ATA_DEV1 = (1 << 4), /* Select Device 1 (slave) */
|
||||
ATA_DEVICE_OBS = (1 << 7) | (1 << 5), /* obs bits in dev reg */
|
||||
ATA_DEVCTL_OBS = (1 << 3), /* obsolete bit in devctl reg */
|
||||
ATA_BUSY = (1 << 7), /* BSY status bit */
|
||||
ATA_DRDY = (1 << 6), /* device ready */
|
||||
ATA_DF = (1 << 5), /* device fault */
|
||||
ATA_DRQ = (1 << 3), /* data request i/o */
|
||||
ATA_ERR = (1 << 0), /* have an error */
|
||||
ATA_SRST = (1 << 2), /* software reset */
|
||||
ATA_ICRC = (1 << 7), /* interface CRC error */
|
||||
ATA_UNC = (1 << 6), /* uncorrectable media error */
|
||||
ATA_IDNF = (1 << 4), /* ID not found */
|
||||
ATA_ABORTED = (1 << 2), /* command aborted */
|
||||
|
||||
/* ATA command block registers */
|
||||
ATA_REG_DATA = 0x00,
|
||||
ATA_REG_ERR = 0x01,
|
||||
ATA_REG_NSECT = 0x02,
|
||||
ATA_REG_LBAL = 0x03,
|
||||
ATA_REG_LBAM = 0x04,
|
||||
ATA_REG_LBAH = 0x05,
|
||||
ATA_REG_DEVICE = 0x06,
|
||||
ATA_REG_STATUS = 0x07,
|
||||
|
||||
ATA_REG_FEATURE = ATA_REG_ERR, /* and their aliases */
|
||||
ATA_REG_CMD = ATA_REG_STATUS,
|
||||
ATA_REG_BYTEL = ATA_REG_LBAM,
|
||||
ATA_REG_BYTEH = ATA_REG_LBAH,
|
||||
ATA_REG_DEVSEL = ATA_REG_DEVICE,
|
||||
ATA_REG_IRQ = ATA_REG_NSECT,
|
||||
|
||||
/* ATA device commands */
|
||||
ATA_CMD_DEV_RESET = 0x08, /* ATAPI device reset */
|
||||
ATA_CMD_PIO_READ = 0x20, /* Read sectors with retry */
|
||||
ATA_CMD_PIO_READ_EXT = 0x24,
|
||||
ATA_CMD_READ_EXT = 0x25,
|
||||
ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
|
||||
ATA_CMD_READ_MULTI_EXT = 0x29,
|
||||
ATA_CMD_READ_LOG_EXT = 0x2f,
|
||||
ATA_CMD_PIO_WRITE = 0x30, /* write sectors with retry */
|
||||
ATA_CMD_PIO_WRITE_EXT = 0x34,
|
||||
ATA_CMD_WRITE_EXT = 0x35,
|
||||
ATA_CMD_SET_MAX_EXT = 0x37,
|
||||
ATA_CMD_WRITE_MULTI_EXT = 0x39,
|
||||
ATA_CMD_WRITE_FUA_EXT = 0x3D,
|
||||
ATA_CMD_VERIFY = 0x40, /* read verify sectors with retry */
|
||||
ATA_CMD_VERIFY_EXT = 0x42,
|
||||
ATA_CMD_FPDMA_READ = 0x60,
|
||||
ATA_CMD_FPDMA_WRITE = 0x61,
|
||||
ATA_CMD_EDD = 0x90, /* execute device diagnostic */
|
||||
ATA_CMD_INIT_DEV_PARAMS = 0x91, /* initialize device parameters */
|
||||
ATA_CMD_PACKET = 0xA0, /* ATAPI packet */
|
||||
ATA_CMD_ID_ATAPI = 0xA1, /* ATAPI identify device */
|
||||
ATA_CMD_CONF_OVERLAY = 0xB1,
|
||||
ATA_CMD_READ_MULTI = 0xC4, /* read multiple */
|
||||
ATA_CMD_WRITE_MULTI = 0xC5, /* write multiple */
|
||||
ATA_CMD_SET_MULTI = 0xC6, /* set multiple mode */
|
||||
ATA_CMD_READ = 0xC8, /* read DMA with retry */
|
||||
ATA_CMD_WRITE = 0xCA, /* write DMA with retry */
|
||||
ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
|
||||
ATA_CMD_STANDBYNOW1 = 0xE0, /* standby immediate */
|
||||
ATA_CMD_IDLEIMMEDIATE = 0xE1, /* idle immediate */
|
||||
ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */
|
||||
ATA_CMD_IDLE = 0xE3, /* place in idle power mode */
|
||||
ATA_CMD_PMP_READ = 0xE4, /* read buffer */
|
||||
ATA_CMD_CHK_POWER = 0xE5, /* check power mode */
|
||||
ATA_CMD_SLEEP = 0xE6, /* sleep */
|
||||
ATA_CMD_FLUSH = 0xE7,
|
||||
ATA_CMD_PMP_WRITE = 0xE8, /* write buffer */
|
||||
ATA_CMD_FLUSH_EXT = 0xEA,
|
||||
ATA_CMD_ID_ATA = 0xEC, /* identify device */
|
||||
ATA_CMD_SET_FEATURES = 0xEF, /* set features */
|
||||
ATA_CMD_SEC_FREEZE_LOCK = 0xF5, /* security freeze */
|
||||
ATA_CMD_READ_NATIVE_MAX = 0xF8,
|
||||
ATA_CMD_SET_MAX = 0xF9,
|
||||
|
||||
/* READ_LOG_EXT pages */
|
||||
ATA_LOG_SATA_NCQ = 0x10,
|
||||
|
||||
/* READ/WRITE LONG (obsolete) */
|
||||
ATA_CMD_READ_LONG = 0x22,
|
||||
ATA_CMD_READ_LONG_ONCE = 0x23,
|
||||
ATA_CMD_WRITE_LONG = 0x32,
|
||||
ATA_CMD_WRITE_LONG_ONCE = 0x33,
|
||||
|
||||
/* SETFEATURES stuff */
|
||||
SETFEATURES_XFER = 0x03,
|
||||
XFER_UDMA_7 = 0x47,
|
||||
XFER_UDMA_6 = 0x46,
|
||||
XFER_UDMA_5 = 0x45,
|
||||
XFER_UDMA_4 = 0x44,
|
||||
XFER_UDMA_3 = 0x43,
|
||||
XFER_UDMA_2 = 0x42,
|
||||
XFER_UDMA_1 = 0x41,
|
||||
XFER_UDMA_0 = 0x40,
|
||||
XFER_MW_DMA_4 = 0x24, /* CFA only */
|
||||
XFER_MW_DMA_3 = 0x23, /* CFA only */
|
||||
XFER_MW_DMA_2 = 0x22,
|
||||
XFER_MW_DMA_1 = 0x21,
|
||||
XFER_MW_DMA_0 = 0x20,
|
||||
XFER_SW_DMA_2 = 0x12,
|
||||
XFER_SW_DMA_1 = 0x11,
|
||||
XFER_SW_DMA_0 = 0x10,
|
||||
XFER_PIO_6 = 0x0E, /* CFA only */
|
||||
XFER_PIO_5 = 0x0D, /* CFA only */
|
||||
XFER_PIO_4 = 0x0C,
|
||||
XFER_PIO_3 = 0x0B,
|
||||
XFER_PIO_2 = 0x0A,
|
||||
XFER_PIO_1 = 0x09,
|
||||
XFER_PIO_0 = 0x08,
|
||||
XFER_PIO_SLOW = 0x00,
|
||||
|
||||
SETFEATURES_WC_ON = 0x02, /* Enable write cache */
|
||||
SETFEATURES_WC_OFF = 0x82, /* Disable write cache */
|
||||
|
||||
SETFEATURES_SPINUP = 0x07, /* Spin-up drive */
|
||||
|
||||
SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */
|
||||
SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
|
||||
|
||||
/* SETFEATURE Sector counts for SATA features */
|
||||
SATA_AN = 0x05, /* Asynchronous Notification */
|
||||
SATA_DIPM = 0x03, /* Device Initiated Power Management */
|
||||
|
||||
/* feature values for SET_MAX */
|
||||
ATA_SET_MAX_ADDR = 0x00,
|
||||
ATA_SET_MAX_PASSWD = 0x01,
|
||||
ATA_SET_MAX_LOCK = 0x02,
|
||||
ATA_SET_MAX_UNLOCK = 0x03,
|
||||
ATA_SET_MAX_FREEZE_LOCK = 0x04,
|
||||
|
||||
/* feature values for DEVICE CONFIGURATION OVERLAY */
|
||||
ATA_DCO_RESTORE = 0xC0,
|
||||
ATA_DCO_FREEZE_LOCK = 0xC1,
|
||||
ATA_DCO_IDENTIFY = 0xC2,
|
||||
ATA_DCO_SET = 0xC3,
|
||||
|
||||
/* ATAPI stuff */
|
||||
ATAPI_PKT_DMA = (1 << 0),
|
||||
ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
|
||||
0=to device, 1=to host */
|
||||
ATAPI_CDB_LEN = 16,
|
||||
|
||||
/* PMP stuff */
|
||||
SATA_PMP_MAX_PORTS = 15,
|
||||
SATA_PMP_CTRL_PORT = 15,
|
||||
|
||||
SATA_PMP_GSCR_DWORDS = 128,
|
||||
SATA_PMP_GSCR_PROD_ID = 0,
|
||||
SATA_PMP_GSCR_REV = 1,
|
||||
SATA_PMP_GSCR_PORT_INFO = 2,
|
||||
SATA_PMP_GSCR_ERROR = 32,
|
||||
SATA_PMP_GSCR_ERROR_EN = 33,
|
||||
SATA_PMP_GSCR_FEAT = 64,
|
||||
SATA_PMP_GSCR_FEAT_EN = 96,
|
||||
|
||||
SATA_PMP_PSCR_STATUS = 0,
|
||||
SATA_PMP_PSCR_ERROR = 1,
|
||||
SATA_PMP_PSCR_CONTROL = 2,
|
||||
|
||||
SATA_PMP_FEAT_BIST = (1 << 0),
|
||||
SATA_PMP_FEAT_PMREQ = (1 << 1),
|
||||
SATA_PMP_FEAT_DYNSSC = (1 << 2),
|
||||
SATA_PMP_FEAT_NOTIFY = (1 << 3),
|
||||
|
||||
/* cable types */
|
||||
ATA_CBL_NONE = 0,
|
||||
ATA_CBL_PATA40 = 1,
|
||||
ATA_CBL_PATA80 = 2,
|
||||
ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */
|
||||
ATA_CBL_PATA_UNK = 4, /* don't know, maybe 80c? */
|
||||
ATA_CBL_PATA_IGN = 5, /* don't know, ignore cable handling */
|
||||
ATA_CBL_SATA = 6,
|
||||
|
||||
/* SATA Status and Control Registers */
|
||||
SCR_STATUS = 0,
|
||||
SCR_ERROR = 1,
|
||||
SCR_CONTROL = 2,
|
||||
SCR_ACTIVE = 3,
|
||||
SCR_NOTIFICATION = 4,
|
||||
|
||||
/* SError bits */
|
||||
SERR_DATA_RECOVERED = (1 << 0), /* recovered data error */
|
||||
SERR_COMM_RECOVERED = (1 << 1), /* recovered comm failure */
|
||||
SERR_DATA = (1 << 8), /* unrecovered data error */
|
||||
SERR_PERSISTENT = (1 << 9), /* persistent data/comm error */
|
||||
SERR_PROTOCOL = (1 << 10), /* protocol violation */
|
||||
SERR_INTERNAL = (1 << 11), /* host internal error */
|
||||
SERR_PHYRDY_CHG = (1 << 16), /* PHY RDY changed */
|
||||
SERR_PHY_INT_ERR = (1 << 17), /* PHY internal error */
|
||||
SERR_COMM_WAKE = (1 << 18), /* Comm wake */
|
||||
SERR_10B_8B_ERR = (1 << 19), /* 10b to 8b decode error */
|
||||
SERR_DISPARITY = (1 << 20), /* Disparity */
|
||||
SERR_CRC = (1 << 21), /* CRC error */
|
||||
SERR_HANDSHAKE = (1 << 22), /* Handshake error */
|
||||
SERR_LINK_SEQ_ERR = (1 << 23), /* Link sequence error */
|
||||
SERR_TRANS_ST_ERROR = (1 << 24), /* Transport state trans. error */
|
||||
SERR_UNRECOG_FIS = (1 << 25), /* Unrecognized FIS */
|
||||
SERR_DEV_XCHG = (1 << 26), /* device exchanged */
|
||||
|
||||
/* struct ata_taskfile flags */
|
||||
ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */
|
||||
ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */
|
||||
ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */
|
||||
ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */
|
||||
ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
|
||||
ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
|
||||
ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
|
||||
|
||||
/* protocol flags */
|
||||
ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
|
||||
ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
|
||||
ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
|
||||
ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
|
||||
ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
|
||||
};
|
||||
|
||||
enum ata_tf_protocols {
|
||||
/* ATA taskfile protocols */
|
||||
ATA_PROT_UNKNOWN, /* unknown/invalid */
|
||||
ATA_PROT_NODATA, /* no data */
|
||||
ATA_PROT_PIO, /* PIO data xfer */
|
||||
ATA_PROT_DMA, /* DMA */
|
||||
ATA_PROT_NCQ, /* NCQ */
|
||||
ATAPI_PROT_NODATA, /* packet command, no data */
|
||||
ATAPI_PROT_PIO, /* packet command, PIO data xfer*/
|
||||
ATAPI_PROT_DMA, /* packet command with special DMA sauce */
|
||||
};
|
||||
|
||||
enum ata_ioctls {
|
||||
ATA_IOC_GET_IO32 = 0x309,
|
||||
ATA_IOC_SET_IO32 = 0x324,
|
||||
};
|
||||
|
||||
enum ata_dev_typed {
|
||||
ATA_DEV_ATA, /* ATA device */
|
||||
ATA_DEV_ATAPI, /* ATAPI device */
|
||||
ATA_DEV_PMP, /* Port Multiplier Port */
|
||||
ATA_DEV_UNKNOWN, /* unknown */
|
||||
};
|
||||
|
||||
struct ata_taskfile {
|
||||
unsigned long flags; /* ATA_TFLAG_xxx */
|
||||
u8 protocol; /* ATA_PROT_xxx */
|
||||
|
||||
u8 ctl; /* control reg */
|
||||
|
||||
u8 hob_feature; /* additional data */
|
||||
u8 hob_nsect; /* to support LBA48 */
|
||||
u8 hob_lbal;
|
||||
u8 hob_lbam;
|
||||
u8 hob_lbah;
|
||||
|
||||
u8 feature;
|
||||
u8 nsect;
|
||||
u8 lbal;
|
||||
u8 lbam;
|
||||
u8 lbah;
|
||||
|
||||
u8 device;
|
||||
|
||||
u8 command; /* IO operation */
|
||||
};
|
||||
|
||||
/*
|
||||
* protocol tests
|
||||
*/
|
||||
static inline unsigned int ata_prot_flags(u8 prot)
|
||||
{
|
||||
switch (prot) {
|
||||
case ATA_PROT_NODATA:
|
||||
return 0;
|
||||
case ATA_PROT_PIO:
|
||||
return ATA_PROT_FLAG_PIO;
|
||||
case ATA_PROT_DMA:
|
||||
return ATA_PROT_FLAG_DMA;
|
||||
case ATA_PROT_NCQ:
|
||||
return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
|
||||
case ATAPI_PROT_NODATA:
|
||||
return ATA_PROT_FLAG_ATAPI;
|
||||
case ATAPI_PROT_PIO:
|
||||
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
|
||||
case ATAPI_PROT_DMA:
|
||||
return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ata_is_atapi(u8 prot)
|
||||
{
|
||||
return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
|
||||
}
|
||||
|
||||
static inline int ata_is_nodata(u8 prot)
|
||||
{
|
||||
return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
|
||||
}
|
||||
|
||||
static inline int ata_is_pio(u8 prot)
|
||||
{
|
||||
return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
|
||||
}
|
||||
|
||||
static inline int ata_is_dma(u8 prot)
|
||||
{
|
||||
return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
|
||||
}
|
||||
|
||||
static inline int ata_is_ncq(u8 prot)
|
||||
{
|
||||
return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
|
||||
}
|
||||
|
||||
static inline int ata_is_data(u8 prot)
|
||||
{
|
||||
return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* id tests
|
||||
*/
|
||||
#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
|
||||
#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
|
||||
#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
|
||||
#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
|
||||
#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
|
||||
#define ata_id_removeable(id) ((id)[0] & (1 << 7))
|
||||
#define ata_id_iordy_disable(id) ((id)[49] & (1 << 10))
|
||||
#define ata_id_has_iordy(id) ((id)[49] & (1 << 11))
|
||||
|
||||
#define ata_id_u32(id,n) \
|
||||
(((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
|
||||
#define ata_id_u64(id,n) \
|
||||
( ((u64) (id)[(n) + 3] << 48) | \
|
||||
((u64) (id)[(n) + 2] << 32) | \
|
||||
((u64) (id)[(n) + 1] << 16) | \
|
||||
((u64) (id)[(n) + 0]) )
|
||||
|
||||
#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
|
||||
|
||||
static inline int ata_id_has_fua(const u16 *id)
|
||||
{
|
||||
if ((id[84] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[84] & (1 << 6);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_flush(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[83] & (1 << 12);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_flush_ext(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[83] & (1 << 13);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_lba48(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
if (!ata_id_u64(id, 100))
|
||||
return 0;
|
||||
return id[83] & (1 << 10);
|
||||
}
|
||||
|
||||
static inline int ata_id_hpa_enabled(const u16 *id)
|
||||
{
|
||||
/* Yes children, word 83 valid bits cover word 82 data */
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
/* And 87 covers 85-87 */
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
/* Check command sets enabled as well as supported */
|
||||
if ((id[85] & ( 1 << 10)) == 0)
|
||||
return 0;
|
||||
return id[82] & (1 << 10);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_wcache(const u16 *id)
|
||||
{
|
||||
/* Yes children, word 83 valid bits cover word 82 data */
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[82] & (1 << 5);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_pm(const u16 *id)
|
||||
{
|
||||
if ((id[83] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[82] & (1 << 3);
|
||||
}
|
||||
|
||||
static inline int ata_id_rahead_enabled(const u16 *id)
|
||||
{
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[85] & (1 << 6);
|
||||
}
|
||||
|
||||
static inline int ata_id_wcache_enabled(const u16 *id)
|
||||
{
|
||||
if ((id[87] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[85] & (1 << 5);
|
||||
}
|
||||
|
||||
static inline unsigned int ata_id_major_version(const u16 *id)
|
||||
{
|
||||
unsigned int mver;
|
||||
|
||||
if (id[ATA_ID_MAJOR_VER] == 0xFFFF)
|
||||
return 0;
|
||||
|
||||
for (mver = 14; mver >= 1; mver--)
|
||||
if (id[ATA_ID_MAJOR_VER] & (1 << mver))
|
||||
break;
|
||||
return mver;
|
||||
}
|
||||
|
||||
static inline int ata_id_is_sata(const u16 *id)
|
||||
{
|
||||
return ata_id_major_version(id) >= 5 && id[93] == 0;
|
||||
}
|
||||
|
||||
static inline int ata_id_has_tpm(const u16 *id)
|
||||
{
|
||||
/* The TPM bits are only valid on ATA8 */
|
||||
if (ata_id_major_version(id) < 8)
|
||||
return 0;
|
||||
if ((id[48] & 0xC000) != 0x4000)
|
||||
return 0;
|
||||
return id[48] & (1 << 0);
|
||||
}
|
||||
|
||||
static inline int ata_id_has_dword_io(const u16 *id)
|
||||
{
|
||||
/* ATA 8 reuses this flag for "trusted" computing */
|
||||
if (ata_id_major_version(id) > 7)
|
||||
return 0;
|
||||
if (id[48] & (1 << 0))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ata_id_current_chs_valid(const u16 *id)
|
||||
{
|
||||
/* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command
|
||||
has not been issued to the device then the values of
|
||||
id[54] to id[56] are vendor specific. */
|
||||
return (id[53] & 0x01) && /* Current translation valid */
|
||||
id[54] && /* cylinders in current translation */
|
||||
id[55] && /* heads in current translation */
|
||||
id[55] <= 16 &&
|
||||
id[56]; /* sectors in current translation */
|
||||
}
|
||||
|
||||
static inline int ata_id_is_cfa(const u16 *id)
|
||||
{
|
||||
u16 v = id[0];
|
||||
if (v == 0x848A) /* Standard CF */
|
||||
return 1;
|
||||
/* Could be CF hiding as standard ATA */
|
||||
if (ata_id_major_version(id) >= 3 && id[82] != 0xFFFF &&
|
||||
(id[82] & ( 1 << 2)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ata_drive_40wire(const u16 *dev_id)
|
||||
{
|
||||
if (ata_id_is_sata(dev_id))
|
||||
return 0; /* SATA */
|
||||
if ((dev_id[93] & 0xE000) == 0x6000)
|
||||
return 0; /* 80 wire */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int ata_drive_40wire_relaxed(const u16 *dev_id)
|
||||
{
|
||||
if ((dev_id[93] & 0x2000) == 0x2000)
|
||||
return 0; /* 80 wire */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int atapi_cdb_len(const u16 *dev_id)
|
||||
{
|
||||
u16 tmp = dev_id[0] & 0x3;
|
||||
switch (tmp) {
|
||||
case 0: return 12;
|
||||
case 1: return 16;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int atapi_command_packet_set(const u16 *dev_id)
|
||||
{
|
||||
return (dev_id[0] >> 8) & 0x1f;
|
||||
}
|
||||
|
||||
static inline int atapi_id_dmadir(const u16 *dev_id)
|
||||
{
|
||||
return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000);
|
||||
}
|
||||
|
||||
static inline int is_multi_taskfile(struct ata_taskfile *tf)
|
||||
{
|
||||
return (tf->command == ATA_CMD_READ_MULTI) ||
|
||||
(tf->command == ATA_CMD_WRITE_MULTI) ||
|
||||
(tf->command == ATA_CMD_READ_MULTI_EXT) ||
|
||||
(tf->command == ATA_CMD_WRITE_MULTI_EXT) ||
|
||||
(tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT);
|
||||
}
|
||||
|
||||
static inline int ata_ok(u8 status)
|
||||
{
|
||||
return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR))
|
||||
== ATA_DRDY);
|
||||
}
|
||||
|
||||
static inline int lba_28_ok(u64 block, u32 n_block)
|
||||
{
|
||||
/* check the ending block number */
|
||||
return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
|
||||
}
|
||||
|
||||
static inline int lba_48_ok(u64 block, u32 n_block)
|
||||
{
|
||||
/* check the ending block number */
|
||||
return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
|
||||
}
|
||||
|
||||
#define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
|
||||
#define sata_pmp_gscr_devid(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16)
|
||||
#define sata_pmp_gscr_rev(gscr) (((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff)
|
||||
#define sata_pmp_gscr_ports(gscr) ((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf)
|
||||
|
||||
u64 ata_id_n_sectors(u16 *id);
|
||||
u32 ata_dev_classify(u32 sig);
|
||||
void ata_id_c_string(const u16 *id, unsigned char *s,
|
||||
unsigned int ofs, unsigned int len);
|
||||
void ata_dump_id(u16 *id);
|
||||
void ata_swap_buf_le16(u16 *buf, unsigned int buf_words);
|
||||
|
||||
#endif /* __LIBATA_H__ */
|
|
@ -0,0 +1,10 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-12-28 lizhirui first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <pci.h>
|
||||
|
||||
rt_uint64_t pci_get_device_map_addr(rt_uint64_t bus,rt_uint64_t device,rt_uint64_t function,rt_uint32_t index)
|
||||
{
|
||||
|
||||
rt_uint64_t device_addr = 0xFE00000000 | (bus << 16) | ((device & 0x1f) << 11) | ((function & 0x07) << 8);
|
||||
struct pci_header *p = (struct pci_header *)(0x9000000000000000UL | device_addr);
|
||||
return 0x9000000000000000UL | ((rt_uint64_t)(p -> BaseAddressRegister[index] & 0xFFFFFFF0));
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-12-28 lizhirui first version
|
||||
*/
|
||||
|
||||
#ifndef __PCI_H__
|
||||
#define __PCI_H__
|
||||
|
||||
struct pci_header
|
||||
{
|
||||
rt_uint16_t VendorID;
|
||||
rt_uint16_t DeviceID;
|
||||
rt_uint16_t Command;
|
||||
rt_uint16_t Status;
|
||||
rt_uint32_t RevisionID : 8;
|
||||
rt_uint32_t ClassCode : 24;
|
||||
rt_uint8_t CachelineSize;
|
||||
rt_uint8_t LatencyTimer;
|
||||
rt_uint8_t HeaderType;
|
||||
rt_uint8_t BIST;
|
||||
rt_uint32_t BaseAddressRegister[6];
|
||||
rt_uint32_t CardbusCISPointer;
|
||||
rt_uint16_t SubsystemVendorID;
|
||||
rt_uint16_t SubsystemID;
|
||||
rt_uint32_t ExpansionROMBaseAddress;
|
||||
rt_uint32_t CapabilitiesPointer : 8;
|
||||
rt_uint32_t resv1 : 24;
|
||||
rt_uint32_t resv2;
|
||||
rt_uint8_t InterruptLine;
|
||||
rt_uint8_t InterruptPin;
|
||||
rt_uint8_t Min_Gnt;
|
||||
rt_uint8_t Max_Lat;
|
||||
};
|
||||
|
||||
rt_uint64_t pci_get_device_map_addr(rt_uint64_t bus,rt_uint64_t device,rt_uint64_t function,rt_uint32_t index);
|
||||
|
||||
#endif
|
|
@ -219,9 +219,9 @@
|
|||
|
||||
/* system packages */
|
||||
|
||||
#define PKG_USING_LWEXT4
|
||||
#define RT_USING_DFS_LWEXT4
|
||||
#define PKG_USING_LWEXT4_LATEST_VERSION
|
||||
|
||||
/* Micrium: Micrium software products porting for RT-Thread */
|
||||
|
||||
|
||||
/* peripheral libraries and drivers */
|
||||
|
||||
|
@ -231,6 +231,9 @@
|
|||
|
||||
/* samples: kernel and components samples */
|
||||
|
||||
|
||||
/* games: games run on RT-Thread console */
|
||||
|
||||
#define SOC_LS2K1000
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue