diff options
author | Mary Ruthven <mruthven@chromium.org> | 2018-07-21 00:41:48 +0000 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-21 01:26:58 -0700 |
commit | f85b863dae721dadb1d15b619cbf26373fb95be2 (patch) | |
tree | 5bb8ac08184e040886ecdb082937a16a7ae24cbc /chip | |
parent | 64f5571960f212bc2085c308d52da1336f6d72a8 (diff) | |
download | chrome-ec-f85b863dae721dadb1d15b619cbf26373fb95be2.tar.gz |
Revert "g: speed up CCD UART processing"
This reverts commit 32b1e3add72159df481ea5e3d86b581ef07caaa3.
Reason for revert: this causes the device to boot into recovery
when running firmware_Cr50DevMode
BUG=b:111701874
BRANCH=cr50
TEST=run firmware_Cr50DevMode --args="iterations=10"
Original change's description:
> g: speed up CCD UART processing
>
> AP and EC consoles may generate a lot of bursty traffic, and cr50 UART
> console to USB processing is very slow: when characters become
> available, a hooks task callback is invoked, which retrieves received
> characters one at a time and queues them up to the appropriate USB
> transmit queue.
>
> This patch speeds up things as follows:
>
> - increases the seize of USB transmit queues for AP and EC console
> channels to 512 bytes. Experiments supported by code
> instrumentation has shown that even this is not enough to avoid
> underruns, but this is a good compromise between memory use and
> performance, these sizes could be revisited later,
>
> - raises UART RX interrupt priority from level 1 to 0
>
> - moving bytes from UART TX FIFO to USB queue happens on the
> interrupt context when UART TX interrupt is asserted
>
> - as many characters as possible are read from the UART first,
> before queuing function is called, and the entire received batch
> is passed to the queuing function.
>
> It has to be mentioned here that presently batch processing is not
> necessarily much more efficient, because queuing function becomes
> more complicated when multiple objects are passed to it, this will
> have to be dealt with in a separate patch.
>
> There is still a lot of room for improvement:
>
> - functions used to queue up data are very generic, dedicated code
> could help a lot.
>
> - UART drivers should have methods for collecting all bytes
> available in receive FIFO in one invocation,
>
> - USB side of things (dequeuing data and passing it to the
> controller.
>
> BRANCH=cr50, cr50mp
> BUG=b:38448364
>
> TEST=ran 'chargen' application on both AP and EC to flood the console
> channels and observed the flow of characters on the host site, it
> is pretty smooth with occasional hiccups, especially when TPM is
> active, before this patch it was impossible to have both stream
> up, both were garbled.
>
> - Verified that new account can be created and user logged in on
> restarts while chargen is running, i.e. TPM task gets enough
> processing bandwidth.
>
> - When EC is reset, there seem to be no lost characters on the
> console (it used to cause some garbled console output before this
> patch). The below output was collected on Coral:
>
> > reboot
> Rebooting!
>
> --- UART initialized after reboot ---
> [Reset cause: soft]
> [Image: RO, coral_v1.1.8363+2cc945d5a 2018-05-15 17:41:57 ...
> [0.003605 init buttons]
> [0.003826 Inits done]
> [0.004094 tablet mode disabled
> ]
> [0.008272 found batt:SMP]
> [0.022278 SW 0x01]
> [0.042247 hash start 0x00040000 0x00021994]
> [0.045823 Battery FET: reg 0x0018 mask 0x0018 disc 0x0000]
> [0.071136 kblight registered]
> [0.071544 PB init-on]
> [0.071818 USB charge p0 m0]
> [0.073670 ID/SKU ADC 4 = 1309 mV]
> [0.075630 ID/SKU ADC 3 = 852 mV]
> [0.076077 SKU ID: 71]
> [0.076335 Motion Sensor Count = 3]
> [0.083594 PD comm enabled]
> ...
>
> - did not test bitbang programming mode, it is in line for
> reworking for speeding up as well.
>
> Change-Id: Ic9f3972f585dd1976169965c2a2422253aeac87a
> Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
> Reviewed-on: https://chromium-review.googlesource.com/1016037
> Reviewed-by: Randall Spangler <rspangler@chromium.org>
> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Bug: b:38448364
Change-Id: I2fbdf4509f6241070f3569d07d869ea667ad4535
Reviewed-on: https://chromium-review.googlesource.com/1145742
Commit-Ready: Mary Ruthven <mruthven@chromium.org>
Tested-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/usart.c | 33 | ||||
-rw-r--r-- | chip/g/usart.h | 26 |
2 files changed, 27 insertions, 32 deletions
diff --git a/chip/g/usart.c b/chip/g/usart.c index 6580ca9eb0..5236acf202 100644 --- a/chip/g/usart.c +++ b/chip/g/usart.c @@ -15,11 +15,6 @@ #define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \ defined(SECTION_IS_RO))) #define QUEUE_SIZE 64 -/* - * Want to be able to accumulate larger amounts of data while USB is - * momentarily stalled for whatever reason. - */ -#define QUEUE_SIZE_UART_RX 512 #ifdef CONFIG_STREAM_SIGNATURE /* @@ -62,8 +57,7 @@ SIGNER_CONFIG(sig, stream_uart, sig_to_usb, ap_uart_output); #else /* Not CONFIG_STREAM_SIGNATURE */ static struct queue const ap_uart_output = - QUEUE_DIRECT(QUEUE_SIZE_UART_RX, uint8_t, - ap_uart.producer, ap_usb.consumer); + QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_uart.producer, ap_usb.consumer); #endif static struct queue const ap_usb_to_uart = @@ -106,8 +100,7 @@ struct usb_stream_config const ec_usb; struct usart_config const ec_uart; static struct queue const ec_uart_to_usb = - QUEUE_DIRECT(QUEUE_SIZE_UART_RX, uint8_t, - ec_uart.producer, ec_usb.consumer); + QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_uart.producer, ec_usb.consumer); static struct queue const ec_usb_to_uart = QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_usb.producer, ec_uart.consumer); @@ -142,26 +135,14 @@ void get_data_from_usb(struct usart_config const *config) void send_data_to_usb(struct usart_config const *config) { - /* - * UART RX FIFO is 32 bytes in size, let's have little extra room so - * that we could catch up if we are draining the FIFO while the chip - * keeps receiving. - */ - uint8_t buffer[50]; - uint32_t i; - uint32_t room; struct queue const *uart_in = config->producer.queue; - int uart = config->uart; - - - i = 0; - room = MIN(sizeof(buffer), queue_space(uart_in)); - while ((i < room) && uartn_rx_available(uart)) - buffer[i++] = uartn_read_char(uart); + /* Copy input from buffer until RX fifo empty or the queue is full */ + while (uartn_rx_available(config->uart) && queue_space(uart_in)) { + int c = uartn_read_char(config->uart); - if (i) - QUEUE_ADD_UNITS(uart_in, buffer, i); + QUEUE_ADD_UNITS(uart_in, &c, 1); + } } static void uart_read(struct producer const *producer, size_t count) diff --git a/chip/g/usart.h b/chip/g/usart.h index dacd7d1850..0be7a920bb 100644 --- a/chip/g/usart.h +++ b/chip/g/usart.h @@ -12,13 +12,24 @@ #ifndef __CROS_FORWARD_UART_H #define __CROS_FORWARD_UART_H +#ifdef CONFIG_STREAM_SIGNATURE +/* + * When configured for signing over streaming data, call the consumer handler + * directly to help avoid incoming uart overruns. + * Note this will run under interrupt handler so consumer beware. + */ #define CONFIGURE_INTERRUPTS__rx_int(NAME) send_data_to_usb(&NAME) +#else +#define CONFIGURE_INTERRUPTS__rx_int(NAME) hook_call_deferred(NAME.deferred, 0) +#endif struct usart_config { int uart; struct producer const producer; struct consumer const consumer; + + const struct deferred_data *deferred; }; extern struct consumer_ops const uart_consumer_ops; @@ -28,7 +39,7 @@ extern struct producer_ops const uart_producer_ops; TXINT) \ void CONCAT2(NAME, _rx_int_)(void); \ void CONCAT2(NAME, _tx_int_)(void); \ - DECLARE_IRQ(RXINT, CONCAT2(NAME, _rx_int_), 0); \ + DECLARE_IRQ(RXINT, CONCAT2(NAME, _rx_int_), 1); \ DECLARE_IRQ(TXINT, CONCAT2(NAME, _tx_int_), 1); \ void CONCAT2(NAME, _tx_int_)(void) \ { \ @@ -52,6 +63,8 @@ extern struct producer_ops const uart_producer_ops; UART, \ RX_QUEUE, \ TX_QUEUE) \ + static void CONCAT2(NAME, _deferred_)(void); \ + DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \ struct usart_config const NAME = { \ .uart = UART, \ .consumer = { \ @@ -62,7 +75,12 @@ extern struct producer_ops const uart_producer_ops; .queue = &RX_QUEUE, \ .ops = &uart_producer_ops, \ }, \ - } + .deferred = &CONCAT2(NAME, _deferred__data), \ + }; \ + static void CONCAT2(NAME, _deferred_)(void) \ + { \ + send_data_to_usb(&NAME); \ + } \ /* Read data from UART and add it to the producer queue */ @@ -70,8 +88,4 @@ void send_data_to_usb(struct usart_config const *config); /* Read data from the consumer queue and send it to the UART */ void get_data_from_usb(struct usart_config const *config); - -/* Helper for UART bitbang mode. */ -extern struct usart_config const ec_uart; - #endif /* __CROS_FORWARD_UART_H */ |