1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2019 Broadcom.
4 */
5
6 #include <bcm_elog.h>
7 #include <io.h>
8
9 static struct bcm_elog global_elog;
10
bcm_elog_putchar(char ch)11 void bcm_elog_putchar(char ch)
12 {
13 struct bcm_elog *elog = &global_elog;
14 uint32_t offset = 0, len = 0;
15 vaddr_t base = 0;
16
17 base = io_pa_or_va(&elog->base, elog->max_size);
18
19 offset = io_read32(base + BCM_ELOG_OFF_OFFSET);
20 len = io_read32(base + BCM_ELOG_LEN_OFFSET);
21 io_write8(base + offset, ch);
22 offset++;
23
24 /* Log buffer is now full and need to wrap around */
25 if (offset >= elog->max_size)
26 offset = BCM_ELOG_HEADER_LEN;
27
28 /* Only increment length when log buffer is not full */
29 if (len < elog->max_size - BCM_ELOG_HEADER_LEN)
30 len++;
31
32 io_write32(base + BCM_ELOG_OFF_OFFSET, offset);
33 io_write32(base + BCM_ELOG_LEN_OFFSET, len);
34 }
35
bcm_elog_init(uintptr_t pa_base,uint32_t size)36 void bcm_elog_init(uintptr_t pa_base, uint32_t size)
37 {
38 struct bcm_elog *elog = &global_elog;
39 uint32_t val = 0;
40 vaddr_t base = 0;
41
42 elog->base.pa = pa_base;
43 elog->max_size = size;
44
45 base = io_pa_or_va(&elog->base, BCM_ELOG_HEADER_LEN);
46
47 /*
48 * If a valid signature is found, it means logging is already
49 * initialized. In this case, we should not re-initialize the entry
50 * header in the designated memory
51 */
52 val = io_read32(base + BCM_ELOG_SIG_OFFSET);
53 if (val != BCM_ELOG_SIG_VAL) {
54 io_write32(base + BCM_ELOG_SIG_OFFSET, BCM_ELOG_SIG_VAL);
55 io_write32(base + BCM_ELOG_OFF_OFFSET, BCM_ELOG_HEADER_LEN);
56 io_write32(base + BCM_ELOG_LEN_OFFSET, 0);
57 }
58 }
59