26 #include <libchip/ata_internal.h> 27 #include <libchip/ide_ctrl_io.h> 28 #include <libchip/ide_ctrl_cfg.h> 36 #define DCTRL_SRST BSP_BBIT8(5) 37 #define DCTRL_NIEN BSP_BBIT8(6) 39 #define DAST_BSY BSP_BBIT8(0) 40 #define DAST_DRDY BSP_BBIT8(1) 41 #define DAST_DRQ BSP_BBIT8(4) 42 #define DAST_ERR BSP_BBIT8(7) 44 #define DST_BSY BSP_BBIT16(0) 45 #define DST_DRDY BSP_BBIT16(1) 46 #define DST_DRQ BSP_BBIT16(4) 47 #define DST_ERR BSP_BBIT16(7) 49 #define DDMA_HUT BSP_BBIT8(1) 50 #define DDMA_FR BSP_BBIT8(2) 51 #define DDMA_FE BSP_BBIT8(3) 52 #define DDMA_IE BSP_BBIT8(4) 53 #define DDMA_UDMA BSP_BBIT8(5) 54 #define DDMA_READ BSP_BBIT8(6) 55 #define DDMA_WRITE BSP_BBIT8(7) 57 #define ATA_SECTOR_SHIFT 9 59 #define ATA_PER_TRANSFER_SECTOR_COUNT_MAX 256 63 uint8_t alternate_status;
64 uint8_t reserved_0[3];
66 uint8_t reserved_1[2];
68 uint8_t reserved_2[3];
70 uint8_t reserved_3[3];
72 uint8_t reserved_4[3];
74 uint8_t reserved_5[3];
75 uint8_t cylinder_high;
76 uint8_t reserved_6[3];
78 uint8_t reserved_7[3];
80 uint8_t reserved_8[2];
85 uint8_t reserved_0[3];
87 uint8_t reserved_1[2];
89 uint8_t reserved_2[3];
91 uint8_t reserved_3[3];
93 uint8_t reserved_4[3];
95 uint8_t reserved_5[3];
96 uint8_t cylinder_high;
97 uint8_t reserved_6[3];
99 uint8_t reserved_7[3];
102 uint8_t reserved_8[2];
106 #define ATA ((volatile ata_drive_registers *) 0xf0003a5c) 108 static inline bool ata_is_data_request(
void)
110 return (ATA->read.alternate_status & DAST_DRQ) != 0;
113 static inline bool ata_is_drive_ready_for_selection(
void)
115 return (ATA->read.alternate_status & (DAST_BSY | DAST_DRQ)) == 0;
118 static inline void ata_wait_400_nano_seconds(
void)
120 ATA->read.alternate_status;
123 static inline void ata_wait_for_drive_ready(
void)
125 while ((ATA->read.alternate_status & (DAST_BSY | DAST_DRQ | DAST_DRDY)) != DAST_DRDY) {
130 static inline void ata_wait_for_not_busy(
void)
132 ata_wait_400_nano_seconds();
134 while ((ATA->read.alternate_status & DAST_BSY) != 0) {
139 static inline bool ata_wait_for_data_request(
void)
141 ata_wait_400_nano_seconds();
143 uint8_t alternate_status;
145 alternate_status = ATA->read.alternate_status;
146 }
while ((alternate_status & DAST_BSY) == DAST_BSY);
148 return (alternate_status & (DAST_ERR | DAST_DRQ)) == DAST_DRQ;
151 static inline bool ata_check_status(
void)
153 return (ATA->read.status & (DST_BSY | DST_ERR)) == 0;
156 static inline void ata_clear_interrupts(
void)
161 static inline uint8_t ata_read_or_write_sectors_command(
bool read)
163 return read ? 0x20 : 0x30;
168 return sector_count > ATA_PER_TRANSFER_SECTOR_COUNT_MAX ?
169 ATA_PER_TRANSFER_SECTOR_COUNT_MAX
173 static inline void ata_flush_sector(uint16_t *begin)
179 void ata_reset_device(
void);
181 bool ata_set_transfer_mode(uint8_t mode);
183 bool ata_execute_io_command(uint8_t command, uint32_t lba, uint32_t sector_count);
187 uint32_t lba = sg->
block;
188 uint32_t sector_count = sg->
length / ATA_SECTOR_SIZE;
189 return ata_execute_io_command(command, lba, sector_count);
205 self->sg_count = sg_count;
206 uint32_t sectors_per_buffer =
self->sg[0].
length >> ATA_SECTOR_SHIFT;
207 self->sg_buffer_offset_mask = sectors_per_buffer - 1;
208 self->sg_index_shift = __builtin_ffs((
int) sectors_per_buffer) - 1;
213 ata_sg_reset(
self,
NULL, 0);
218 ata_sg_reset(
self, sg, sg_count);
223 return self->sg[0].block;
228 return (self->sg_buffer_offset_mask + 1) *
self->sg_count;
233 uint16_t *begin = (uint16_t *)(self->sg[relative_sector >> self->sg_index_shift].buffer);
235 return begin + ((relative_sector &
self->sg_buffer_offset_mask) << (ATA_SECTOR_SHIFT - 1));
238 static inline uint16_t *ata_sg_get_sector_data_end(
const ata_sg_context *
self, uint16_t *begin)
240 return begin + ATA_SECTOR_SIZE / 2;
253 static inline void ata_driver_lock(
const ata_driver *
self)
260 static inline void ata_driver_unlock(
const ata_driver *
self)
267 static inline bool ata_driver_is_card_present(
const ata_driver *
self)
269 return self->card_present;
272 static inline void ata_driver_io_request(
281 uint32_t sg_count = request->
bufnum;
282 ata_driver_lock(
self);
283 bool ok = (*transfer)(
self,
read, sg, sg_count);
284 ata_driver_unlock(
self);
286 rtems_blkdev_request_done(request, sc);
289 static inline int ata_driver_io_control(
299 case RTEMS_BLKIO_REQUEST:
302 case RTEMS_BLKIO_CAPABILITIES:
310 int ata_driver_io_control_pio_polled(
330 void ata_driver_dma_pio_single_create(
332 const char *device_file_path,
ssize_t read(int fd, void *buffer, size_t count)
Definition: read.c:27
uint32_t rtems_blkdev_bnum
Block device block index type.
Definition: diskdevs.h:45
int(* rtems_block_device_ioctl)(rtems_disk_device *dd, uint32_t req, void *argp)
Block device IO control handler type.
Definition: diskdevs.h:50
ssize_t write(int fd, const void *buffer, size_t count)
Definition: write.c:30
uint32_t bufnum
Definition: blkdev.h:126
void rtems_cache_flush_multiple_data_lines(const void *d_addr, size_t n_bytes)
Flushes multiple data cache lines.
Definition: cacheimpl.h:109
Description of a disk device (logical and physical disks).
Definition: diskdevs.h:157
Information for the Assert Handler.
General purpose assembler macros, linker command file support and some inline functions for direct re...
The block device transfer request is used to read or write a number of blocks from or to the device.
Definition: blkdev.h:102
rtems_status_code
Classic API Status.
Definition: status.h:43
rtems_status_code rtems_semaphore_release(rtems_id id)
RTEMS Semaphore Release.
Definition: semrelease.c:28
rtems_status_code rtems_semaphore_obtain(rtems_id id, rtems_option option_set, rtems_interval timeout)
RTEMS Obtain Semaphore.
Definition: semobtain.c:51
Block Device Disk Management API.
Block device scatter or gather buffer structure.
Definition: blkdev.h:68
#define RTEMS_WAIT
Definition: options.h:53
Definition: bestcomm.h:127
Definition: intercom.c:74
rtems_blkdev_bnum block
Definition: blkdev.h:72
#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT
Only consecutive multi-sector buffer requests are supported.
Definition: blkdev.h:264
uint32_t length
Definition: blkdev.h:77
int rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
Common IO control primitive.
Definition: blkdev-ioctl.c:24
#define RTEMS_NO_TIMEOUT
Constant for indefinite wait.
Definition: rtems.h:174
Objects_Id rtems_id
Used to manage and manipulate RTEMS object identifiers.
Definition: types.h:83
rtems_blkdev_request_op req
Definition: blkdev.h:106
rtems_blkdev_sg_buffer bufs[RTEMS_ZERO_LENGTH_ARRAY]
Definition: blkdev.h:145
Block Device Buffer Management.
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77