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:108
Description of a disk device (logical and physical disks).
Definition: diskdevs.h:157
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:27
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:23
#define RTEMS_NO_TIMEOUT
Constant for indefinite wait.
Definition: rtems.h:170
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