xref: /openbmc/qemu/hw/block/xen_blkif.h (revision ab67678a59e31d30b0f8587cdc245f93c2e56fef)
12a6a4076SMarkus Armbruster #ifndef XEN_BLKIF_H
22a6a4076SMarkus Armbruster #define XEN_BLKIF_H
347b43a1fSPaolo Bonzini 
4*a3434a2dSAnthony PERARD #include "hw/xen/interface/io/blkif.h"
5*a3434a2dSAnthony PERARD #include "hw/xen/interface/io/protocols.h"
647b43a1fSPaolo Bonzini 
70d8e5894SJuergen Gross /*
80d8e5894SJuergen Gross  * Not a real protocol.  Used to generate ring structs which contain
947b43a1fSPaolo Bonzini  * the elements common to all protocols only.  This way we get a
1047b43a1fSPaolo Bonzini  * compiler-checkable way to use common struct elements, so we can
110d8e5894SJuergen Gross  * avoid using switch(protocol) in a number of places.
120d8e5894SJuergen Gross  */
1347b43a1fSPaolo Bonzini struct blkif_common_request {
1447b43a1fSPaolo Bonzini     char dummy;
1547b43a1fSPaolo Bonzini };
1647b43a1fSPaolo Bonzini struct blkif_common_response {
1747b43a1fSPaolo Bonzini     char dummy;
1847b43a1fSPaolo Bonzini };
1947b43a1fSPaolo Bonzini 
2047b43a1fSPaolo Bonzini /* i386 protocol version */
2147b43a1fSPaolo Bonzini #pragma pack(push, 4)
2247b43a1fSPaolo Bonzini struct blkif_x86_32_request {
2347b43a1fSPaolo Bonzini     uint8_t        operation;        /* BLKIF_OP_???                         */
2447b43a1fSPaolo Bonzini     uint8_t        nr_segments;      /* number of segments                   */
2547b43a1fSPaolo Bonzini     blkif_vdev_t   handle;           /* only for read/write requests         */
2647b43a1fSPaolo Bonzini     uint64_t       id;               /* private guest value, echoed in resp  */
2747b43a1fSPaolo Bonzini     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
2847b43a1fSPaolo Bonzini     struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
2947b43a1fSPaolo Bonzini };
3016246018SJuergen Gross struct blkif_x86_32_request_discard {
3116246018SJuergen Gross     uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
3216246018SJuergen Gross     uint8_t        flag;             /* nr_segments in request struct        */
3316246018SJuergen Gross     blkif_vdev_t   handle;           /* only for read/write requests         */
3416246018SJuergen Gross     uint64_t       id;               /* private guest value, echoed in resp  */
3516246018SJuergen Gross     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
3616246018SJuergen Gross     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
3716246018SJuergen Gross };
3847b43a1fSPaolo Bonzini struct blkif_x86_32_response {
3947b43a1fSPaolo Bonzini     uint64_t        id;              /* copied from request */
4047b43a1fSPaolo Bonzini     uint8_t         operation;       /* copied from request */
4147b43a1fSPaolo Bonzini     int16_t         status;          /* BLKIF_RSP_???       */
4247b43a1fSPaolo Bonzini };
4347b43a1fSPaolo Bonzini typedef struct blkif_x86_32_request blkif_x86_32_request_t;
4447b43a1fSPaolo Bonzini typedef struct blkif_x86_32_response blkif_x86_32_response_t;
4547b43a1fSPaolo Bonzini #pragma pack(pop)
4647b43a1fSPaolo Bonzini 
4747b43a1fSPaolo Bonzini /* x86_64 protocol version */
4847b43a1fSPaolo Bonzini struct blkif_x86_64_request {
4947b43a1fSPaolo Bonzini     uint8_t        operation;        /* BLKIF_OP_???                         */
5047b43a1fSPaolo Bonzini     uint8_t        nr_segments;      /* number of segments                   */
5147b43a1fSPaolo Bonzini     blkif_vdev_t   handle;           /* only for read/write requests         */
5247b43a1fSPaolo Bonzini     uint64_t       __attribute__((__aligned__(8))) id;
5347b43a1fSPaolo Bonzini     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
5447b43a1fSPaolo Bonzini     struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
5547b43a1fSPaolo Bonzini };
5616246018SJuergen Gross struct blkif_x86_64_request_discard {
5716246018SJuergen Gross     uint8_t        operation;        /* BLKIF_OP_DISCARD                     */
5816246018SJuergen Gross     uint8_t        flag;             /* nr_segments in request struct        */
5916246018SJuergen Gross     blkif_vdev_t   handle;           /* only for read/write requests         */
6016246018SJuergen Gross     uint64_t       __attribute__((__aligned__(8))) id;
6116246018SJuergen Gross     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
6216246018SJuergen Gross     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
6316246018SJuergen Gross };
6447b43a1fSPaolo Bonzini struct blkif_x86_64_response {
6547b43a1fSPaolo Bonzini     uint64_t       __attribute__((__aligned__(8))) id;
6647b43a1fSPaolo Bonzini     uint8_t         operation;       /* copied from request */
6747b43a1fSPaolo Bonzini     int16_t         status;          /* BLKIF_RSP_???       */
6847b43a1fSPaolo Bonzini };
6947b43a1fSPaolo Bonzini typedef struct blkif_x86_64_request blkif_x86_64_request_t;
7047b43a1fSPaolo Bonzini typedef struct blkif_x86_64_response blkif_x86_64_response_t;
7147b43a1fSPaolo Bonzini 
720d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
730d8e5894SJuergen Gross                   struct blkif_common_response);
740d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
750d8e5894SJuergen Gross                   struct blkif_x86_32_response);
760d8e5894SJuergen Gross DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
770d8e5894SJuergen Gross                   struct blkif_x86_64_response);
7847b43a1fSPaolo Bonzini 
7947b43a1fSPaolo Bonzini union blkif_back_rings {
8047b43a1fSPaolo Bonzini     blkif_back_ring_t        native;
8147b43a1fSPaolo Bonzini     blkif_common_back_ring_t common;
8247b43a1fSPaolo Bonzini     blkif_x86_32_back_ring_t x86_32_part;
8347b43a1fSPaolo Bonzini     blkif_x86_64_back_ring_t x86_64_part;
8447b43a1fSPaolo Bonzini };
8547b43a1fSPaolo Bonzini typedef union blkif_back_rings blkif_back_rings_t;
8647b43a1fSPaolo Bonzini 
8747b43a1fSPaolo Bonzini enum blkif_protocol {
8847b43a1fSPaolo Bonzini     BLKIF_PROTOCOL_NATIVE = 1,
8947b43a1fSPaolo Bonzini     BLKIF_PROTOCOL_X86_32 = 2,
9047b43a1fSPaolo Bonzini     BLKIF_PROTOCOL_X86_64 = 3,
9147b43a1fSPaolo Bonzini };
9247b43a1fSPaolo Bonzini 
blkif_get_x86_32_req(blkif_request_t * dst,blkif_x86_32_request_t * src)930d8e5894SJuergen Gross static inline void blkif_get_x86_32_req(blkif_request_t *dst,
940d8e5894SJuergen Gross                                         blkif_x86_32_request_t *src)
9547b43a1fSPaolo Bonzini {
9647b43a1fSPaolo Bonzini     int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
9747b43a1fSPaolo Bonzini 
9847b43a1fSPaolo Bonzini     dst->operation = src->operation;
9947b43a1fSPaolo Bonzini     dst->nr_segments = src->nr_segments;
10047b43a1fSPaolo Bonzini     dst->handle = src->handle;
10147b43a1fSPaolo Bonzini     dst->id = src->id;
10247b43a1fSPaolo Bonzini     dst->sector_number = src->sector_number;
1034837a1a5SJan Beulich     /* Prevent the compiler from using src->... instead. */
1044837a1a5SJan Beulich     barrier();
1054837a1a5SJan Beulich     if (dst->operation == BLKIF_OP_DISCARD) {
10616246018SJuergen Gross         struct blkif_x86_32_request_discard *s = (void *)src;
107f3135204SOlaf Hering         struct blkif_request_discard *d = (void *)dst;
108f3135204SOlaf Hering         d->nr_sectors = s->nr_sectors;
109f3135204SOlaf Hering         return;
110f3135204SOlaf Hering     }
1110d8e5894SJuergen Gross     if (n > dst->nr_segments) {
112f9e98e5dSStefano Stabellini         n = dst->nr_segments;
1130d8e5894SJuergen Gross     }
1140d8e5894SJuergen Gross     for (i = 0; i < n; i++) {
11547b43a1fSPaolo Bonzini         dst->seg[i] = src->seg[i];
11647b43a1fSPaolo Bonzini     }
1170d8e5894SJuergen Gross }
11847b43a1fSPaolo Bonzini 
blkif_get_x86_64_req(blkif_request_t * dst,blkif_x86_64_request_t * src)1190d8e5894SJuergen Gross static inline void blkif_get_x86_64_req(blkif_request_t *dst,
1200d8e5894SJuergen Gross                                         blkif_x86_64_request_t *src)
12147b43a1fSPaolo Bonzini {
12247b43a1fSPaolo Bonzini     int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
12347b43a1fSPaolo Bonzini 
12447b43a1fSPaolo Bonzini     dst->operation = src->operation;
12547b43a1fSPaolo Bonzini     dst->nr_segments = src->nr_segments;
12647b43a1fSPaolo Bonzini     dst->handle = src->handle;
12747b43a1fSPaolo Bonzini     dst->id = src->id;
12847b43a1fSPaolo Bonzini     dst->sector_number = src->sector_number;
1294837a1a5SJan Beulich     /* Prevent the compiler from using src->... instead. */
1304837a1a5SJan Beulich     barrier();
1314837a1a5SJan Beulich     if (dst->operation == BLKIF_OP_DISCARD) {
13216246018SJuergen Gross         struct blkif_x86_64_request_discard *s = (void *)src;
133f3135204SOlaf Hering         struct blkif_request_discard *d = (void *)dst;
134f3135204SOlaf Hering         d->nr_sectors = s->nr_sectors;
135f3135204SOlaf Hering         return;
136f3135204SOlaf Hering     }
1370d8e5894SJuergen Gross     if (n > dst->nr_segments) {
138f9e98e5dSStefano Stabellini         n = dst->nr_segments;
1390d8e5894SJuergen Gross     }
1400d8e5894SJuergen Gross     for (i = 0; i < n; i++) {
14147b43a1fSPaolo Bonzini         dst->seg[i] = src->seg[i];
14247b43a1fSPaolo Bonzini     }
1430d8e5894SJuergen Gross }
14447b43a1fSPaolo Bonzini 
1452bcd05cfSPaul Durrant #define XEN_BLKIF_SECTOR_SIZE 512
1462bcd05cfSPaul Durrant 
1472a6a4076SMarkus Armbruster #endif /* XEN_BLKIF_H */
148