[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH 10/10] ehci: Use __attribute__((aligned()))



* Using that attribute is a bit nicer than trying to do the alignment
  manually. It will blow up the QH size to 256 bytes, but we can
  probably live with that.
* Use the same attribute for fat QHs and qTDs; we will need this (at
  least for QHs) when creating an array of QHs/qTDs so that they are
  properly aligned.

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
 ehci/ehci.h | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/ehci/ehci.h b/ehci/ehci.h
index d37f141..fb8dd9e 100644
--- a/ehci/ehci.h
+++ b/ehci/ehci.h
@@ -23,6 +23,7 @@
 #ifndef EHCI_H
 #define EHCI_H
 
+#include <assert.h>
 #include <stddef.h>
 #include <stdint.h>
 
@@ -62,43 +63,40 @@ struct ehci_qtd {
 
     // 64-bit structures
     uint32_t ext_buffer[5];
-} __attribute__((packed));
+} __attribute__((packed, aligned(128)));
+
+static_assert(!(sizeof(struct ehci_qtd) % 128),
+              "sizeof(ehci_qtd) must be a multiple of 128");
 
 struct ehci_qh {
     uint32_t next_qh;
     uint32_t ep_state[2];
     uint32_t current_qtd;
     struct ehci_qtd overlay;
-} __attribute__((packed));
+} __attribute__((packed, aligned(128)));
+
+static_assert(!(sizeof(struct ehci_qh) % 128),
+              "sizeof(ehci_qh) must be a multiple of 128");
 
 typedef struct ehci_fat_qh ehci_fat_qh_t;
 typedef struct ehci_fat_qtd ehci_fat_qtd_t;
 
-#define DIFF_TO_MULTIPLE(value, divisor) \
-    ((divisor) - ((((value) + (divisor) - 1) % (divisor)) + 1))
-
 struct ehci_fat_qh {
     volatile struct ehci_qh qh;
 
-    // Align the QH to 128 bytes (something with cache lines?). Otherwise,
-    // there may be conflicts between data we are writing to our very own
-    // fields provided by ehci_fat_qh_t and writes done by the HC to this
-    // structure.
-    uint8_t alignment[DIFF_TO_MULTIPLE(sizeof(struct ehci_qh), 128)];
-
     struct cdi_mem_area *cdi_mem_area;
     uintptr_t paddr;
 
     ehci_fat_qh_t *next, *previous;
     ehci_fat_qtd_t *first_qtd, *last_qtd;
-};
+} __attribute__((aligned(64)));
+
+static_assert(!(sizeof(struct ehci_fat_qh) % 64),
+              "sizeof(ehci_fat_qh) must be a multiple of 64");
 
 struct ehci_fat_qtd {
     volatile struct ehci_qtd qtd;
 
-    // Align the qTD to a multiple of 128 bytes.
-    uint8_t alignment[DIFF_TO_MULTIPLE(sizeof(struct ehci_qtd), 128)];
-
     struct cdi_mem_area *cdi_mem_area;
     uintptr_t paddr;
 
@@ -111,7 +109,10 @@ struct ehci_fat_qtd {
     size_t write_back_size;
 
     cdi_usb_transmission_result_t *result;
-};
+} __attribute__((aligned(64)));
+
+static_assert(!(sizeof(struct ehci_fat_qtd) % 64),
+              "sizeof(ehci_fat_qtd) must be a multiple of 64");
 
 struct ehci {
     struct cdi_usb_hc hc;
-- 
2.6.4