summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Georgi <pgeorgi@google.com>2018-08-16 15:35:43 +0200
committerCommit Bot <commit-bot@chromium.org>2021-04-20 14:25:31 +0000
commit6cf7f36327327ba56c8a88aef1240a76752cb499 (patch)
tree498336b883c96120daf3a60f151c7e573aad8067
parent5a6da9ae9b28dff5273419e7322672f305a28984 (diff)
downloadchrome-ec-6cf7f36327327ba56c8a88aef1240a76752cb499.tar.gz
chip/stm32: Convert usb_endpoints to C so gcc's LTO knows about it
If we keep it assembly-only, the link time optimizer gets confused and eliminates seemingly unused functions, to then replace references to them with the "no handler" defaults in a later step. Similar approach as with vecttable: Implement the table in C so LTO knows the entire story. BUG=b:65441143 BRANCH=none TEST=usb_ep_{rx,tx,event} and usb_iface_request look more reasonable in disassembly on whiskers. Change-Id: I35ccfd68cda2d0022aa464ecf622f4eef71c3398 Signed-off-by: Patrick Georgi <pgeorgi@google.com> Reviewed-on: https://chromium-review.googlesource.com/1177710 Commit-Ready: Patrick Georgi <pgeorgi@chromium.org> Tested-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@chromium.org> (cherry picked from commit 69bc0deb614cc131cd669b5ac8935e68d10ac6e5) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2723461 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Patrick Georgi <pgeorgi@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--chip/stm32/usb_endpoints.S108
-rw-r--r--chip/stm32/usb_endpoints.c169
-rw-r--r--core/cortex-m0/ec.lds.S4
3 files changed, 173 insertions, 108 deletions
diff --git a/chip/stm32/usb_endpoints.S b/chip/stm32/usb_endpoints.S
deleted file mode 100644
index 9b3c41d175..0000000000
--- a/chip/stm32/usb_endpoints.S
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * USB endpoints/interfaces callbacks declaration
- */
-
-#include "config.h"
-
-.section .rodata.usb_ep
-
-.macro endpoint number suffix
-.if \number < USB_EP_COUNT
-.long ep_\number\()_\()\suffix
-.weak ep_\number\()_\()\suffix
-.set ep_\number\()_\()\suffix, ep_undefined
-.endif
-.endm
-
-.macro interface number
-.if \number < USB_IFACE_COUNT
-.long iface_\number\()_request
-.weak iface_\number\()_request
-.set iface_\number\()_request, iface_undefined
-.endif
-.endm
-
-/* align function pointers on a 32-bit boundary */
-.align 2
-/* Endpoint callbacks */
-.global usb_ep_tx
-usb_ep_tx:
-endpoint 0 tx
-endpoint 1 tx
-endpoint 2 tx
-endpoint 3 tx
-endpoint 4 tx
-endpoint 5 tx
-endpoint 6 tx
-endpoint 7 tx
-endpoint 8 tx
-endpoint 9 tx
-endpoint 10 tx
-endpoint 11 tx
-endpoint 12 tx
-endpoint 13 tx
-endpoint 14 tx
-endpoint 15 tx
-
-.global usb_ep_rx
-usb_ep_rx:
-endpoint 0 rx
-endpoint 1 rx
-endpoint 2 rx
-endpoint 3 rx
-endpoint 4 rx
-endpoint 5 rx
-endpoint 6 rx
-endpoint 7 rx
-endpoint 8 rx
-endpoint 9 rx
-endpoint 10 rx
-endpoint 11 rx
-endpoint 12 rx
-endpoint 13 rx
-endpoint 14 rx
-endpoint 15 rx
-
-.global usb_ep_event
-usb_ep_event:
-endpoint 0 evt
-endpoint 1 evt
-endpoint 2 evt
-endpoint 3 evt
-endpoint 4 evt
-endpoint 5 evt
-endpoint 6 evt
-endpoint 7 evt
-endpoint 8 evt
-endpoint 9 evt
-endpoint 10 evt
-endpoint 11 evt
-endpoint 12 evt
-endpoint 13 evt
-endpoint 14 evt
-endpoint 15 evt
-
-.global usb_iface_request
-usb_iface_request:
-interface 0
-interface 1
-interface 2
-interface 3
-interface 4
-interface 5
-interface 6
-interface 7
-
-.text
-.code 16
-
-.thumb_func
-/* Undefined interface callbacks fail by returning non-zero*/
-iface_undefined:
- mov r0, #1
-.thumb_func
-ep_undefined:
- bx lr
diff --git a/chip/stm32/usb_endpoints.c b/chip/stm32/usb_endpoints.c
new file mode 100644
index 0000000000..e4d595c31d
--- /dev/null
+++ b/chip/stm32/usb_endpoints.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * USB endpoints/interfaces callbacks declaration
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "config.h"
+#include "common.h"
+#include "usb_hw.h"
+
+typedef void (*xfer_func)(void);
+typedef void (*evt_func) (enum usb_ep_event evt);
+
+#if defined(CHIP_FAMILY_STM32F4)
+#define iface_arguments struct usb_setup_packet *req
+#else
+#define iface_arguments usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx
+#endif
+typedef int (*iface_func)(iface_arguments);
+
+#ifndef PASS
+#define PASS 1
+#endif
+
+#if PASS == 1
+void ep_undefined(void)
+{
+ return;
+}
+
+void ep_evt_undefined(enum usb_ep_event evt)
+{
+ return;
+}
+
+/* Undefined interface callbacks fail by returning non-zero*/
+int iface_undefined(iface_arguments)
+{
+ return 1;
+}
+
+#define table(type, name, x) x
+
+#define endpoint_tx(number) \
+ extern void __attribute__((used, weak, alias("ep_undefined"))) \
+ ep_ ## number ## _tx(void);
+#define endpoint_rx(number) \
+ extern void __attribute__((used, weak, alias("ep_undefined"))) \
+ ep_ ## number ## _rx(void);
+#define endpoint_evt(number) \
+ extern void __attribute__((used, weak, alias("ep_evt_undefined"))) \
+ ep_ ## number ## _evt(enum usb_ep_event evt);
+#define interface(number) \
+ extern int __attribute__((used, weak, alias("iface_undefined"))) \
+ iface_ ## number ## _request(iface_arguments);
+
+#define null
+
+#endif /* PASS 1 */
+
+#if PASS == 2
+#undef table
+#undef endpoint_tx
+#undef endpoint_rx
+#undef endpoint_evt
+#undef interface
+#undef null
+
+/* align function pointers on a 32-bit boundary */
+#define table(type, name, x) type name[] __attribute__((aligned(4), section(".rodata.usb_ep." #name ",\"a\" @"))) = { x };
+#define null (void*)0
+
+#define ep_(num, suf) CONCAT3(ep_, num, suf)
+#define ep(num, suf) ep_(num, suf)
+
+#define endpoint_tx(number) \
+ [number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_ ## number ## _tx,
+#define endpoint_rx(number) \
+ [number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_ ## number ## _rx,
+#define endpoint_evt(number) \
+ [number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_ ## number ## _evt,
+#define interface(number) \
+ [number < USB_IFACE_COUNT ? number : USB_IFACE_COUNT - 1] = iface_ ## number ## _request,
+#endif /* PASS 2 */
+
+/*
+ * The initializers are listed backwards, but that's so that the items beyond
+ * the chip's limit are first assigned to the last field, then overwritten by
+ * its actual value due to the designated initializers in the macros above.
+ * It all sorts out nicely
+ */
+table(xfer_func, usb_ep_tx,
+ endpoint_tx(15)
+ endpoint_tx(14)
+ endpoint_tx(13)
+ endpoint_tx(12)
+ endpoint_tx(11)
+ endpoint_tx(10)
+ endpoint_tx(9)
+ endpoint_tx(8)
+ endpoint_tx(7)
+ endpoint_tx(6)
+ endpoint_tx(5)
+ endpoint_tx(4)
+ endpoint_tx(3)
+ endpoint_tx(2)
+ endpoint_tx(1)
+ endpoint_tx(0)
+)
+
+table(xfer_func, usb_ep_rx,
+ endpoint_rx(15)
+ endpoint_rx(14)
+ endpoint_rx(13)
+ endpoint_rx(12)
+ endpoint_rx(11)
+ endpoint_rx(10)
+ endpoint_rx(9)
+ endpoint_rx(8)
+ endpoint_rx(7)
+ endpoint_rx(6)
+ endpoint_rx(5)
+ endpoint_rx(4)
+ endpoint_rx(3)
+ endpoint_rx(2)
+ endpoint_rx(1)
+ endpoint_rx(0)
+)
+
+table(evt_func, usb_ep_event,
+ endpoint_evt(15)
+ endpoint_evt(14)
+ endpoint_evt(13)
+ endpoint_evt(12)
+ endpoint_evt(11)
+ endpoint_evt(10)
+ endpoint_evt(9)
+ endpoint_evt(8)
+ endpoint_evt(7)
+ endpoint_evt(6)
+ endpoint_evt(5)
+ endpoint_evt(4)
+ endpoint_evt(3)
+ endpoint_evt(2)
+ endpoint_evt(1)
+ endpoint_evt(0)
+)
+
+#if USB_IFACE_COUNT > 0
+table(iface_func, usb_iface_request,
+ interface(7)
+ interface(6)
+ interface(5)
+ interface(4)
+ interface(3)
+ interface(2)
+ interface(1)
+ interface(0)
+)
+#endif
+
+#if PASS == 1
+#undef PASS
+#define PASS 2
+#include "usb_endpoints.c"
+#endif
diff --git a/core/cortex-m0/ec.lds.S b/core/cortex-m0/ec.lds.S
index 3a982427c9..e211926664 100644
--- a/core/cortex-m0/ec.lds.S
+++ b/core/cortex-m0/ec.lds.S
@@ -158,6 +158,10 @@ SECTIONS
__usb_desc_end = .;
. = ALIGN(4);
KEEP(*(.rodata.usb_ep))
+ KEEP(*(.rodata.usb_ep.usb_ep_tx))
+ KEEP(*(.rodata.usb_ep.usb_ep_rx))
+ KEEP(*(.rodata.usb_ep.usb_ep_event))
+ KEEP(*(.rodata.usb_ep.usb_iface_request))
. = ALIGN(4);
*(.rodata*)