[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