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