blob: 4c14b69c5162ad4a7fff5ab5e7bbd1abc2dd9cec [file] [log] [blame]
Julius Werner385176d2017-06-13 15:53:45 -07001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm_macros.S>
Soby Mathew58873ae2018-10-10 16:03:09 +01008#define USE_FINISH_CONSOLE_REG_2
Julius Werner385176d2017-06-13 15:53:45 -07009#include <console_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <drivers/coreboot/cbmem_console.h>
Julius Werner385176d2017-06-13 15:53:45 -070011
12/*
13 * This driver implements access to coreboot's in-memory console
14 * (CBMEM console). For the original implementation, see
15 * <coreboot>/src/lib/cbmem_console.c.
16 */
17
18 .globl console_cbmc_register
19 .globl console_cbmc_putc
20 .globl console_cbmc_flush
21
22 /* -----------------------------------------------
Antonio Nino Diaz992c5ac2018-10-08 13:26:48 +010023 * int console_cbmc_register(uintptr_t base,
24 * console_cbmc_t *console);
Julius Werner385176d2017-06-13 15:53:45 -070025 * Registers a new CBMEM console instance. Reads
26 * the size field from the buffer header structure
27 * and stores it in our console_cbmc_t struct, so
28 * that we keep the size in secure memory where we
29 * can trust it. A malicious EL1 could manipulate
30 * the console buffer (including the header), so we
31 * must not trust its contents after boot.
32 * In: x0 - CBMEM console base address
33 * x1 - pointer to empty console_cbmc_t struct
34 * Out: x0 - 1 to indicate success
35 * Clobber list: x0, x1, x2, x7
36 * -----------------------------------------------
37 */
38func console_cbmc_register
39 str x0, [x1, #CONSOLE_T_CBMC_BASE]
40 ldr w2, [x0]
41 str w2, [x1, #CONSOLE_T_CBMC_SIZE]
42 mov x0, x1
Soby Mathew58873ae2018-10-10 16:03:09 +010043 finish_console_register cbmc putc=1, flush=1
Julius Werner385176d2017-06-13 15:53:45 -070044endfunc console_cbmc_register
45
46 /* -----------------------------------------------
47 * int console_cbmc_puts(int c, console_cbmc_t *console)
48 * Writes a character to the CBMEM console buffer,
49 * including overflow handling of the cursor field.
50 * The character must be preserved in x0.
51 * In: x0 - character to be stored
52 * x1 - pointer to console_cbmc_t struct
53 * Clobber list: x1, x2, x16, x17
54 * -----------------------------------------------
55 */
56func console_cbmc_putc
57 ldr w2, [x1, #CONSOLE_T_CBMC_SIZE]
58 ldr x1, [x1, #CONSOLE_T_CBMC_BASE]
59 add x1, x1, #8 /* keep address of body in x1 */
60
61 ldr w16, [x1, #-4] /* load cursor (one u32 before body) */
62 and w17, w16, #0xf0000000 /* keep flags part in w17 */
63 and w16, w16, #0x0fffffff /* keep actual cursor part in w16 */
64
65 cmp w16, w2 /* sanity check that cursor < size */
66 b.lo putc_within_bounds
67 mov w0, #-1 /* cursor >= size must be malicious */
68 ret /* so return error, don't write char */
69
70putc_within_bounds:
71 strb w0, [x1, w16, uxtw] /* body[cursor] = character */
72 add w16, w16, #1 /* cursor++ */
73 cmp w16, w2 /* if cursor < size... */
74 b.lo putc_write_back /* ...skip overflow handling */
75
76 mov w16, #0 /* on overflow, set cursor back to 0 */
77 orr w17, w17, #(1 << 31) /* and set overflow flag */
78
79putc_write_back:
80 orr w16, w16, w17 /* merge cursor and flags back */
81 str w16, [x1, #-4] /* write back cursor to memory */
82 ret
83endfunc console_cbmc_putc
84
85 /* -----------------------------------------------
86 * int console_cbmc_flush(console_cbmc_t *console)
87 * Flushes the CBMEM console by flushing the
88 * console buffer from the CPU's data cache.
89 * In: x0 - pointer to console_cbmc_t struct
90 * Out: x0 - 0 for success
91 * Clobber list: x0, x1, x2, x3, x5
92 * -----------------------------------------------
93 */
94func console_cbmc_flush
95 mov x5, x30
96 ldr x1, [x0, #CONSOLE_T_CBMC_SIZE]
97 ldr x0, [x0, #CONSOLE_T_CBMC_BASE]
98 add x1, x1, #8 /* add size of console header */
99 bl clean_dcache_range /* (clobbers x2 and x3) */
100 mov x0, #0
101 ret x5
102endfunc console_cbmc_flush