File indexing completed on 2025-05-11 08:23:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef GEN5200_ATA_H
0029 #define GEN5200_ATA_H
0030
0031 #include "bestcomm.h"
0032
0033 #include <assert.h>
0034
0035 #include <rtems.h>
0036 #include <rtems/diskdevs.h>
0037 #include <rtems/bdbuf.h>
0038
0039 #include <libchip/ata_internal.h>
0040 #include <libchip/ide_ctrl_io.h>
0041 #include <libchip/ide_ctrl_cfg.h>
0042
0043 #include <libcpu/powerpc-utility.h>
0044
0045 #ifdef __cplusplus
0046 extern "C" {
0047 #endif
0048
0049 #define DCTRL_SRST BSP_BBIT8(5)
0050 #define DCTRL_NIEN BSP_BBIT8(6)
0051
0052 #define DAST_BSY BSP_BBIT8(0)
0053 #define DAST_DRDY BSP_BBIT8(1)
0054 #define DAST_DRQ BSP_BBIT8(4)
0055 #define DAST_ERR BSP_BBIT8(7)
0056
0057 #define DST_BSY BSP_BBIT16(0)
0058 #define DST_DRDY BSP_BBIT16(1)
0059 #define DST_DRQ BSP_BBIT16(4)
0060 #define DST_ERR BSP_BBIT16(7)
0061
0062 #define DDMA_HUT BSP_BBIT8(1)
0063 #define DDMA_FR BSP_BBIT8(2)
0064 #define DDMA_FE BSP_BBIT8(3)
0065 #define DDMA_IE BSP_BBIT8(4)
0066 #define DDMA_UDMA BSP_BBIT8(5)
0067 #define DDMA_READ BSP_BBIT8(6)
0068 #define DDMA_WRITE BSP_BBIT8(7)
0069
0070 #define ATA_SECTOR_SHIFT 9
0071
0072 #define ATA_PER_TRANSFER_SECTOR_COUNT_MAX 256
0073
0074 typedef union {
0075 struct {
0076 uint8_t alternate_status;
0077 uint8_t reserved_0[3];
0078 uint16_t data;
0079 uint8_t reserved_1[2];
0080 uint8_t error;
0081 uint8_t reserved_2[3];
0082 uint8_t sector_count;
0083 uint8_t reserved_3[3];
0084 uint8_t sector;
0085 uint8_t reserved_4[3];
0086 uint8_t cylinder_low;
0087 uint8_t reserved_5[3];
0088 uint8_t cylinder_high;
0089 uint8_t reserved_6[3];
0090 uint8_t head;
0091 uint8_t reserved_7[3];
0092 uint16_t status;
0093 uint8_t reserved_8[2];
0094 } read;
0095
0096 struct {
0097 uint8_t control;
0098 uint8_t reserved_0[3];
0099 uint16_t data;
0100 uint8_t reserved_1[2];
0101 uint8_t feature;
0102 uint8_t reserved_2[3];
0103 uint8_t sector_count;
0104 uint8_t reserved_3[3];
0105 uint8_t sector;
0106 uint8_t reserved_4[3];
0107 uint8_t cylinder_low;
0108 uint8_t reserved_5[3];
0109 uint8_t cylinder_high;
0110 uint8_t reserved_6[3];
0111 uint8_t head;
0112 uint8_t reserved_7[3];
0113 uint8_t command;
0114 uint8_t dma_control;
0115 uint8_t reserved_8[2];
0116 } write;
0117 } ata_drive_registers;
0118
0119 #define ATA ((volatile ata_drive_registers *) 0xf0003a5c)
0120
0121 static inline bool ata_is_data_request(void)
0122 {
0123 return (ATA->read.alternate_status & DAST_DRQ) != 0;
0124 }
0125
0126 static inline bool ata_is_drive_ready_for_selection(void)
0127 {
0128 return (ATA->read.alternate_status & (DAST_BSY | DAST_DRQ)) == 0;
0129 }
0130
0131 static inline void ata_wait_400_nano_seconds(void)
0132 {
0133 ATA->read.alternate_status;
0134 }
0135
0136 static inline void ata_wait_for_drive_ready(void)
0137 {
0138 while ((ATA->read.alternate_status & (DAST_BSY | DAST_DRQ | DAST_DRDY)) != DAST_DRDY) {
0139
0140 }
0141 }
0142
0143 static inline void ata_wait_for_not_busy(void)
0144 {
0145 ata_wait_400_nano_seconds();
0146
0147 while ((ATA->read.alternate_status & DAST_BSY) != 0) {
0148
0149 }
0150 }
0151
0152 static inline bool ata_wait_for_data_request(void)
0153 {
0154 ata_wait_400_nano_seconds();
0155
0156 uint8_t alternate_status;
0157 do {
0158 alternate_status = ATA->read.alternate_status;
0159 } while ((alternate_status & DAST_BSY) == DAST_BSY);
0160
0161 return (alternate_status & (DAST_ERR | DAST_DRQ)) == DAST_DRQ;
0162 }
0163
0164 static inline bool ata_check_status(void)
0165 {
0166 return (ATA->read.status & (DST_BSY | DST_ERR)) == 0;
0167 }
0168
0169 static inline void ata_clear_interrupts(void)
0170 {
0171 ATA->read.status;
0172 }
0173
0174 static inline uint8_t ata_read_or_write_sectors_command(bool read)
0175 {
0176 return read ? 0x20 : 0x30;
0177 }
0178
0179 static inline rtems_blkdev_bnum ata_max_transfer_count(rtems_blkdev_bnum sector_count)
0180 {
0181 return sector_count > ATA_PER_TRANSFER_SECTOR_COUNT_MAX ?
0182 ATA_PER_TRANSFER_SECTOR_COUNT_MAX
0183 : sector_count;
0184 }
0185
0186 static inline void ata_flush_sector(uint16_t *begin)
0187 {
0188
0189 rtems_cache_flush_multiple_data_lines(begin, ATA_SECTOR_SIZE);
0190 }
0191
0192 void ata_reset_device(void);
0193
0194 bool ata_set_transfer_mode(uint8_t mode);
0195
0196 bool ata_execute_io_command(uint8_t command, uint32_t lba, uint32_t sector_count);
0197
0198 static inline bool ata_execute_io_command_with_sg(uint8_t command, const rtems_blkdev_sg_buffer *sg)
0199 {
0200 uint32_t lba = sg->block;
0201 uint32_t sector_count = sg->length / ATA_SECTOR_SIZE;
0202 return ata_execute_io_command(command, lba, sector_count);
0203 }
0204
0205 typedef struct {
0206 const rtems_blkdev_sg_buffer *sg;
0207
0208 size_t sg_count;
0209
0210 rtems_blkdev_bnum sg_buffer_offset_mask;
0211
0212 int sg_index_shift;
0213 } ata_sg_context;
0214
0215 static inline void ata_sg_reset(ata_sg_context *self, const rtems_blkdev_sg_buffer *sg, size_t sg_count)
0216 {
0217 self->sg = sg;
0218 self->sg_count = sg_count;
0219 uint32_t sectors_per_buffer = self->sg[0].length >> ATA_SECTOR_SHIFT;
0220 self->sg_buffer_offset_mask = sectors_per_buffer - 1;
0221 self->sg_index_shift = __builtin_ffs((int) sectors_per_buffer) - 1;
0222 }
0223
0224 static inline void ata_sg_create_default(ata_sg_context *self)
0225 {
0226 ata_sg_reset(self, NULL, 0);
0227 }
0228
0229 static inline void ata_sg_create(ata_sg_context *self, const rtems_blkdev_sg_buffer *sg, size_t sg_count)
0230 {
0231 ata_sg_reset(self, sg, sg_count);
0232 }
0233
0234 static inline rtems_blkdev_bnum ata_sg_get_start_sector(const ata_sg_context *self)
0235 {
0236 return self->sg[0].block;
0237 }
0238
0239 static inline rtems_blkdev_bnum ata_sg_get_sector_count(const ata_sg_context *self)
0240 {
0241 return (self->sg_buffer_offset_mask + 1) * self->sg_count;
0242 }
0243
0244 static inline uint16_t *ata_sg_get_sector_data_begin(const ata_sg_context *self, rtems_blkdev_bnum relative_sector)
0245 {
0246 uint16_t *begin = (uint16_t *)(self->sg[relative_sector >> self->sg_index_shift].buffer);
0247
0248 return begin + ((relative_sector & self->sg_buffer_offset_mask) << (ATA_SECTOR_SHIFT - 1));
0249 }
0250
0251 static inline uint16_t *ata_sg_get_sector_data_end(const ata_sg_context *self, uint16_t *begin)
0252 {
0253 return begin + ATA_SECTOR_SIZE / 2;
0254 }
0255
0256 typedef struct {
0257 rtems_id lock;
0258
0259 bool card_present;
0260 } ata_driver;
0261
0262 void ata_driver_create(ata_driver *self, const char *device_file_path, rtems_block_device_ioctl io_control);
0263
0264 void ata_driver_destroy(ata_driver *self);
0265
0266 static inline void ata_driver_lock(const ata_driver *self)
0267 {
0268 rtems_status_code sc = rtems_semaphore_obtain(self->lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0269 assert(sc == RTEMS_SUCCESSFUL);
0270 (void) sc;
0271 }
0272
0273 static inline void ata_driver_unlock(const ata_driver *self)
0274 {
0275 rtems_status_code sc = rtems_semaphore_release(self->lock);
0276 assert(sc == RTEMS_SUCCESSFUL);
0277 (void) sc;
0278 }
0279
0280 static inline bool ata_driver_is_card_present(const ata_driver *self)
0281 {
0282 return self->card_present;
0283 }
0284
0285 static inline void ata_driver_io_request(
0286 ata_driver *self,
0287 rtems_blkdev_request *request,
0288 bool (*transfer)(ata_driver *, bool, rtems_blkdev_sg_buffer *, size_t)
0289 )
0290 {
0291 assert(request->req == RTEMS_BLKDEV_REQ_READ || request->req == RTEMS_BLKDEV_REQ_WRITE);
0292 bool read = request->req != RTEMS_BLKDEV_REQ_WRITE;
0293 rtems_blkdev_sg_buffer *sg = &request->bufs[0];
0294 uint32_t sg_count = request->bufnum;
0295 ata_driver_lock(self);
0296 bool ok = (*transfer)(self, read, sg, sg_count);
0297 ata_driver_unlock(self);
0298 rtems_status_code sc = ok ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
0299 rtems_blkdev_request_done(request, sc);
0300 }
0301
0302 static inline int ata_driver_io_control(
0303 rtems_disk_device *dd,
0304 uint32_t cmd,
0305 void *arg,
0306 bool (*transfer)(ata_driver *, bool, rtems_blkdev_sg_buffer *, size_t)
0307 )
0308 {
0309 ata_driver *self = (ata_driver *) rtems_disk_get_driver_data(dd);
0310
0311 switch (cmd) {
0312 case RTEMS_BLKIO_REQUEST:
0313 ata_driver_io_request(self, (rtems_blkdev_request *) arg, transfer);
0314 return 0;
0315 case RTEMS_BLKIO_CAPABILITIES:
0316 *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
0317 return 0;
0318 default:
0319 return rtems_blkdev_ioctl(dd, cmd, arg);
0320 }
0321 }
0322
0323 int ata_driver_io_control_pio_polled(
0324 rtems_disk_device *dd,
0325 uint32_t cmd,
0326 void *arg
0327 );
0328
0329 typedef struct {
0330 ata_driver super;
0331
0332 bestcomm_task task;
0333
0334 bool read;
0335
0336 ata_sg_context sg_context;
0337
0338 rtems_blkdev_bnum transfer_current;
0339
0340 rtems_blkdev_bnum transfer_end;
0341 } ata_driver_dma_pio_single;
0342
0343 void ata_driver_dma_pio_single_create(
0344 ata_driver_dma_pio_single *self,
0345 const char *device_file_path,
0346 TaskId task_index
0347 );
0348
0349 #ifdef __cplusplus
0350 }
0351 #endif
0352
0353 #endif