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 21 void htif_lock_global(void) 22 { 23 cpu_spin_lock(&htif_global_lock); 24 } 25 26 void htif_unlock_global(void) 27 { 28 cpu_spin_unlock(&htif_global_lock); 29 } 30 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 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 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 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 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