source: rtems/bsps/powerpc/gen5200/include/bsp/ata.h @ 2afb22b

5
Last change on this file since 2afb22b was 2afb22b, checked in by Chris Johns <chrisj@…>, on Dec 23, 2017 at 7:18:56 AM

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 8.0 KB
Line 
1/*
2 * Copyright (c) 2010-2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifndef GEN5200_ATA_H
16#define GEN5200_ATA_H
17
18#include "bestcomm.h"
19
20#include <assert.h>
21
22#include <rtems.h>
23#include <rtems/diskdevs.h>
24#include <rtems/bdbuf.h>
25
26#include <libchip/ata_internal.h>
27#include <libchip/ide_ctrl_io.h>
28#include <libchip/ide_ctrl_cfg.h>
29
30#include <libcpu/powerpc-utility.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif /* __cplusplus */
35
36#define DCTRL_SRST BSP_BBIT8(5)
37#define DCTRL_NIEN BSP_BBIT8(6)
38
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)
43
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)
48
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)
56
57#define ATA_SECTOR_SHIFT 9
58
59#define ATA_PER_TRANSFER_SECTOR_COUNT_MAX 256
60
61typedef union {
62  struct {
63    uint8_t alternate_status;
64    uint8_t reserved_0[3];
65    uint16_t data;
66    uint8_t reserved_1[2];
67    uint8_t error;
68    uint8_t reserved_2[3];
69    uint8_t sector_count;
70    uint8_t reserved_3[3];
71    uint8_t sector;
72    uint8_t reserved_4[3];
73    uint8_t cylinder_low;
74    uint8_t reserved_5[3];
75    uint8_t cylinder_high;
76    uint8_t reserved_6[3];
77    uint8_t head;
78    uint8_t reserved_7[3];
79    uint16_t status;
80    uint8_t reserved_8[2];
81  } read;
82
83  struct {
84    uint8_t control;
85    uint8_t reserved_0[3];
86    uint16_t data;
87    uint8_t reserved_1[2];
88    uint8_t feature;
89    uint8_t reserved_2[3];
90    uint8_t sector_count;
91    uint8_t reserved_3[3];
92    uint8_t sector;
93    uint8_t reserved_4[3];
94    uint8_t cylinder_low;
95    uint8_t reserved_5[3];
96    uint8_t cylinder_high;
97    uint8_t reserved_6[3];
98    uint8_t head;
99    uint8_t reserved_7[3];
100    uint8_t command;
101    uint8_t dma_control;
102    uint8_t reserved_8[2];
103  } write;
104} ata_drive_registers;
105
106#define ATA ((volatile ata_drive_registers *) 0xf0003a5c)
107
108static inline bool ata_is_data_request(void)
109{
110  return (ATA->read.alternate_status & DAST_DRQ) != 0;
111}
112
113static inline bool ata_is_drive_ready_for_selection(void)
114{
115  return (ATA->read.alternate_status & (DAST_BSY | DAST_DRQ)) == 0;
116}
117
118static inline void ata_wait_400_nano_seconds(void)
119{
120  ATA->read.alternate_status;
121}
122
123static inline void ata_wait_for_drive_ready(void)
124{
125  while ((ATA->read.alternate_status & (DAST_BSY | DAST_DRQ | DAST_DRDY)) != DAST_DRDY) {
126    /* Wait */
127  }
128}
129
130static inline void ata_wait_for_not_busy(void)
131{
132  ata_wait_400_nano_seconds();
133
134  while ((ATA->read.alternate_status & DAST_BSY) != 0) {
135    /* Wait */
136  }
137}
138
139static inline bool ata_wait_for_data_request(void)
140{
141  ata_wait_400_nano_seconds();
142
143  uint8_t alternate_status;
144  do {
145    alternate_status = ATA->read.alternate_status;
146  } while ((alternate_status & DAST_BSY) == DAST_BSY);
147
148  return (alternate_status & (DAST_ERR | DAST_DRQ)) == DAST_DRQ;
149}
150
151static inline bool ata_check_status(void)
152{
153  return (ATA->read.status & (DST_BSY | DST_ERR)) == 0;
154}
155
156static inline void ata_clear_interrupts(void)
157{
158  ATA->read.status;
159}
160
161static inline uint8_t ata_read_or_write_sectors_command(bool read)
162{
163  return read ? 0x20 : 0x30;
164}
165
166static inline rtems_blkdev_bnum ata_max_transfer_count(rtems_blkdev_bnum sector_count)
167{
168  return sector_count > ATA_PER_TRANSFER_SECTOR_COUNT_MAX ?
169    ATA_PER_TRANSFER_SECTOR_COUNT_MAX
170      : sector_count;
171}
172
173static inline void ata_flush_sector(uint16_t *begin)
174{
175  /* XXX: The dcbi operation does not work properly */
176  rtems_cache_flush_multiple_data_lines(begin, ATA_SECTOR_SIZE);
177}
178
179void ata_reset_device(void);
180
181bool ata_set_transfer_mode(uint8_t mode);
182
183bool ata_execute_io_command(uint8_t command, uint32_t lba, uint32_t sector_count);
184
185static inline bool ata_execute_io_command_with_sg(uint8_t command, const rtems_blkdev_sg_buffer *sg)
186{
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);
190}
191
192typedef struct {
193  const rtems_blkdev_sg_buffer *sg;
194
195  size_t sg_count;
196
197  rtems_blkdev_bnum sg_buffer_offset_mask;
198
199  int sg_index_shift;
200} ata_sg_context;
201
202static inline void ata_sg_reset(ata_sg_context *self, const rtems_blkdev_sg_buffer *sg, size_t sg_count)
203{
204  self->sg = sg;
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;
209}
210
211static inline void ata_sg_create_default(ata_sg_context *self)
212{
213  ata_sg_reset(self, NULL, 0);
214}
215
216static inline void ata_sg_create(ata_sg_context *self, const rtems_blkdev_sg_buffer *sg, size_t sg_count)
217{
218  ata_sg_reset(self, sg, sg_count);
219}
220
221static inline rtems_blkdev_bnum ata_sg_get_start_sector(const ata_sg_context *self)
222{
223  return self->sg[0].block;
224}
225
226static inline rtems_blkdev_bnum ata_sg_get_sector_count(const ata_sg_context *self)
227{
228  return (self->sg_buffer_offset_mask + 1) * self->sg_count;
229}
230
231static inline uint16_t *ata_sg_get_sector_data_begin(const ata_sg_context *self, rtems_blkdev_bnum relative_sector)
232{
233  uint16_t *begin = (uint16_t *)(self->sg[relative_sector >> self->sg_index_shift].buffer);
234
235  return begin + ((relative_sector & self->sg_buffer_offset_mask) << (ATA_SECTOR_SHIFT - 1));
236}
237
238static inline uint16_t *ata_sg_get_sector_data_end(const ata_sg_context *self, uint16_t *begin)
239{
240  return begin + ATA_SECTOR_SIZE / 2;
241}
242
243typedef struct {
244  rtems_id lock;
245
246  bool card_present;
247} ata_driver;
248
249void ata_driver_create(ata_driver *self, const char *device_file_path, rtems_block_device_ioctl io_control);
250
251void ata_driver_destroy(ata_driver *self);
252
253static inline void ata_driver_lock(const ata_driver *self)
254{
255  rtems_status_code sc = rtems_semaphore_obtain(self->lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
256  assert(sc == RTEMS_SUCCESSFUL);
257}
258
259static inline void ata_driver_unlock(const ata_driver *self)
260{
261  rtems_status_code sc = rtems_semaphore_release(self->lock);
262  assert(sc == RTEMS_SUCCESSFUL);
263}
264
265static inline bool ata_driver_is_card_present(const ata_driver *self)
266{
267  return self->card_present;
268}
269
270static inline void ata_driver_io_request(
271  ata_driver *self,
272  rtems_blkdev_request *request,
273  bool (*transfer)(ata_driver *, bool, rtems_blkdev_sg_buffer *, size_t)
274)
275{
276  assert(request->req == RTEMS_BLKDEV_REQ_READ || request->req == RTEMS_BLKDEV_REQ_WRITE);
277  bool read = request->req != RTEMS_BLKDEV_REQ_WRITE;
278  rtems_blkdev_sg_buffer *sg = &request->bufs[0];
279  uint32_t sg_count = request->bufnum;
280  ata_driver_lock(self);
281  bool ok = (*transfer)(self, read, sg, sg_count);
282  ata_driver_unlock(self);
283  rtems_status_code sc = ok ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR;
284  rtems_blkdev_request_done(request, sc);
285}
286
287static inline int ata_driver_io_control(
288  rtems_disk_device *dd,
289  uint32_t cmd,
290  void *arg,
291  bool (*transfer)(ata_driver *, bool, rtems_blkdev_sg_buffer *, size_t)
292)
293{
294  ata_driver *self = (ata_driver *) rtems_disk_get_driver_data(dd);
295
296  switch (cmd) {
297    case RTEMS_BLKIO_REQUEST:
298      ata_driver_io_request(self, (rtems_blkdev_request *) arg, transfer);
299      return 0;
300    case RTEMS_BLKIO_CAPABILITIES:
301      *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
302      return 0;
303    default:
304      return rtems_blkdev_ioctl(dd, cmd, arg);
305  }
306}
307
308int ata_driver_io_control_pio_polled(
309  rtems_disk_device *dd,
310  uint32_t cmd,
311  void *arg
312);
313
314typedef struct {
315  ata_driver super;
316
317  bestcomm_task task;
318
319  bool read;
320
321  ata_sg_context sg_context;
322
323  rtems_blkdev_bnum transfer_current;
324
325  rtems_blkdev_bnum transfer_end;
326} ata_driver_dma_pio_single;
327
328void ata_driver_dma_pio_single_create(
329  ata_driver_dma_pio_single *self,
330  const char *device_file_path,
331  TaskId task_index
332);
333
334#ifdef __cplusplus
335}
336#endif /* __cplusplus */
337
338#endif /* GEN5200_ATA_H */
Note: See TracBrowser for help on using the repository browser.