diff options
author | Patrick Georgi <pgeorgi@google.com> | 2018-08-16 15:35:43 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-16 10:30:37 -0700 |
commit | f3ee6eab984aa6855dea035b7771540280371b34 (patch) | |
tree | 2281612c4f94f00ac59d98bbb2e9d72f254f9cc1 /chip | |
parent | 69bc0deb614cc131cd669b5ac8935e68d10ac6e5 (diff) | |
download | chrome-ec-f3ee6eab984aa6855dea035b7771540280371b34.tar.gz |
chip/g: 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,reset} and usb_iface_request look more reasonable in
disassembly on cr50.
Change-Id: I72103af742164c29aac38e9929d1a83d8c154b53
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1177711
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>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/usb_endpoints.S | 107 | ||||
-rw-r--r-- | chip/g/usb_endpoints.c | 158 |
2 files changed, 158 insertions, 107 deletions
diff --git a/chip/g/usb_endpoints.S b/chip/g/usb_endpoints.S deleted file mode 100644 index cc13cadeb3..0000000000 --- a/chip/g/usb_endpoints.S +++ /dev/null @@ -1,107 +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_reset -usb_ep_reset: -endpoint 0 rst -endpoint 1 rst -endpoint 2 rst -endpoint 3 rst -endpoint 4 rst -endpoint 5 rst -endpoint 6 rst -endpoint 7 rst -endpoint 8 rst -endpoint 9 rst -endpoint 10 rst -endpoint 11 rst -endpoint 12 rst -endpoint 13 rst -endpoint 14 rst -endpoint 15 rst - -.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 -ep_undefined: - bx lr diff --git a/chip/g/usb_endpoints.c b/chip/g/usb_endpoints.c new file mode 100644 index 0000000000..0cf73e2b13 --- /dev/null +++ b/chip/g/usb_endpoints.c @@ -0,0 +1,158 @@ +/* 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" +#include "common.h" +#include "usb_hw.h" + +typedef void (*xfer_func)(void); +typedef void (*rst_func) (void); +typedef int (*iface_func)(struct usb_setup_packet *req); +#ifndef PASS +#define PASS 1 +#endif + +#if PASS == 1 +void ep_undefined(void) +{ + return; +} + +void ep_rst_undefined(void) +{ + return; +} + +/* Undefined interface callbacks fail by returning non-zero*/ +int iface_undefined(struct usb_setup_packet *req) +{ + 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_rst(number) \ + extern void __attribute__((used, weak, alias("ep_rst_undefined"))) \ + ep_ ## number ## _rst(void); +#define interface(number) \ + extern int __attribute__((used, weak, alias("iface_undefined"))) \ + iface_ ## number ## _request(struct usb_setup_packet *req); + +#define null + +#endif /* PASS 1 */ + +#if PASS == 2 +#undef table +#undef endpoint_tx +#undef endpoint_rx +#undef endpoint_rst +#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_rst(number) \ + [number < USB_EP_COUNT ? number : USB_EP_COUNT - 1] = ep_ ## number ## _rst, +#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(rst_func, usb_ep_reset, + endpoint_rst(15) + endpoint_rst(14) + endpoint_rst(13) + endpoint_rst(12) + endpoint_rst(11) + endpoint_rst(10) + endpoint_rst(9) + endpoint_rst(8) + endpoint_rst(7) + endpoint_rst(6) + endpoint_rst(5) + endpoint_rst(4) + endpoint_rst(3) + endpoint_rst(2) + endpoint_rst(1) + endpoint_rst(0) +) + +table(iface_func, usb_iface_request, + interface(7) + interface(6) + interface(5) + interface(4) + interface(3) + interface(2) + interface(1) + interface(0) +) + +#if PASS == 1 +#undef PASS +#define PASS 2 +#include "usb_endpoints.c" +#endif |