1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2022 NXP
4 */
5
6 #include <compiler.h>
7 #include <io.h>
8 #include <kernel/spinlock.h>
9 #include <stdint.h>
10 #include <util.h>
11
12 #include "htif.h"
13
14 static unsigned int htif_global_lock __nex_bss = SPINLOCK_UNLOCK;
15
16 #ifdef HTIF_BASE
17 register_phys_mem(MEM_AREA_IO_NSEC, HTIF_BASE,
18 ROUNDUP(HTIF_REG_SIZE, CORE_MMU_PGDIR_SIZE));
19 #endif
20
htif_lock_global(void)21 void htif_lock_global(void)
22 {
23 cpu_spin_lock(&htif_global_lock);
24 }
25
htif_unlock_global(void)26 void htif_unlock_global(void)
27 {
28 cpu_spin_unlock(&htif_global_lock);
29 }
30
chip_to_base(struct serial_chip * chip)31 static vaddr_t chip_to_base(struct serial_chip *chip)
32 {
33 struct htif_console_data *pd =
34 container_of(chip, struct htif_console_data, chip);
35
36 return io_pa_or_va(&pd->base, HTIF_REG_SIZE);
37 }
38
tohost_cmd(vaddr_t base,uint64_t dev,uint64_t cmd,uint64_t data)39 static void __maybe_unused tohost_cmd(vaddr_t base, uint64_t dev,
40 uint64_t cmd, uint64_t data)
41 {
42 while (io_read64(base))
43 barrier();
44
45 io_write64(base, SHIFT_U64(dev, 56) | SHIFT_U64(cmd, 48) | data);
46 }
47
htif_console_putc(struct serial_chip * chip,int ch __maybe_unused)48 static void htif_console_putc(struct serial_chip *chip,
49 int ch __maybe_unused)
50 {
51 #ifdef RV64
52 vaddr_t base = 0;
53
54 htif_lock_global();
55 base = chip_to_base(chip);
56 tohost_cmd(base, HTIF_DEV_CONSOLE, HTIF_CMD_WRITE, ch);
57 htif_unlock_global();
58 #else
59 #warning HTIF is not supported on RV32
60 #endif
61 }
62
htif_console_flush(struct serial_chip * chip __unused)63 static void htif_console_flush(struct serial_chip *chip __unused)
64 {
65 }
66
67 static const struct serial_ops htif_console_ops = {
68 .flush = htif_console_flush,
69 .putc = htif_console_putc,
70 };
71 DECLARE_KEEP_PAGER(htif_console_ops);
72
htif_console_init(struct htif_console_data * pd,paddr_t pbase)73 void htif_console_init(struct htif_console_data *pd, paddr_t pbase)
74 {
75 pd->base.pa = pbase;
76 pd->chip.ops = &htif_console_ops;
77 }
78