From 8b2be6c33e07761051bca9024c536663027f031a Mon Sep 17 00:00:00 2001 From: Hesham Almatary Date: Mon, 31 Jul 2023 15:11:38 +0100 Subject: [PATCH] morello: Add support for QEMU platform This was tested on a baseline AArch64 Morello/QEMU without CHERI. Basic support for a PL011 driver. Signed-off-by: Hesham Almatary --- .../morello-qemu/platsupport/plat/clock.h | 19 +++++ .../morello-qemu/platsupport/plat/i2c.h | 11 +++ .../morello-qemu/platsupport/plat/serial.h | 22 ++++++ .../src/plat/morello-qemu/chardev.c | 41 ++++++++++ libplatsupport/src/plat/morello-qemu/serial.c | 75 +++++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 libplatsupport/plat_include/morello-qemu/platsupport/plat/clock.h create mode 100644 libplatsupport/plat_include/morello-qemu/platsupport/plat/i2c.h create mode 100644 libplatsupport/plat_include/morello-qemu/platsupport/plat/serial.h create mode 100644 libplatsupport/src/plat/morello-qemu/chardev.c create mode 100644 libplatsupport/src/plat/morello-qemu/serial.c diff --git a/libplatsupport/plat_include/morello-qemu/platsupport/plat/clock.h b/libplatsupport/plat_include/morello-qemu/platsupport/plat/clock.h new file mode 100644 index 000000000..fb97328c4 --- /dev/null +++ b/libplatsupport/plat_include/morello-qemu/platsupport/plat/clock.h @@ -0,0 +1,19 @@ +/* + * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +enum clk_id { + CLK_MASTER, + /* ----- */ + NCLOCKS, + /* Custom clock */ + CLK_CUSTOM, +}; + +enum clock_gate { + NCLKGATES +}; diff --git a/libplatsupport/plat_include/morello-qemu/platsupport/plat/i2c.h b/libplatsupport/plat_include/morello-qemu/platsupport/plat/i2c.h new file mode 100644 index 000000000..72a143526 --- /dev/null +++ b/libplatsupport/plat_include/morello-qemu/platsupport/plat/i2c.h @@ -0,0 +1,11 @@ +/* + * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +enum i2c_id { + NI2C +}; diff --git a/libplatsupport/plat_include/morello-qemu/platsupport/plat/serial.h b/libplatsupport/plat_include/morello-qemu/platsupport/plat/serial.h new file mode 100644 index 000000000..2604a31d4 --- /dev/null +++ b/libplatsupport/plat_include/morello-qemu/platsupport/plat/serial.h @@ -0,0 +1,22 @@ +/* + * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#define UART0_PADDR 0x9000000 + +#define UART0_IRQ 33 + +enum chardev_id { + PL001_UART0, + /* Aliases */ + PS_SERIAL0 = PL001_UART0, + /* defaults */ + PS_SERIAL_DEFAULT = PL001_UART0 +}; + +#define DEFAULT_SERIAL_PADDR UART0_PADDR +#define DEFAULT_SERIAL_INTERRUPT UART0_IRQ diff --git a/libplatsupport/src/plat/morello-qemu/chardev.c b/libplatsupport/src/plat/morello-qemu/chardev.c new file mode 100644 index 000000000..2a4407403 --- /dev/null +++ b/libplatsupport/src/plat/morello-qemu/chardev.c @@ -0,0 +1,41 @@ +/* + * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/** + * Contains the definition for all character devices on this platform. + * Currently this is just a simple patch. + */ + +#include "../../chardev.h" +#include "../../common.h" +#include + +#include "../../chardev.h" + +static const int uart0_irqs[] = {UART0_IRQ, -1}; + +#define UART_DEFN(devid) { \ + .id = PL001_UART##devid, \ + .paddr = UART##devid##_PADDR, \ + .size = BIT(12), \ + .irqs = uart##devid##_irqs, \ + .init_fn = &uart_init \ +} + +static const struct dev_defn dev_defn[] = { + UART_DEFN(0), +}; + +struct ps_chardevice *ps_cdev_init(enum chardev_id id, const ps_io_ops_t *o, struct ps_chardevice *d) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(dev_defn); i++) { + if (dev_defn[i].id == id) { + return (dev_defn[i].init_fn(dev_defn + i, o, d)) ? NULL : d; + } + } + return NULL; +} diff --git a/libplatsupport/src/plat/morello-qemu/serial.c b/libplatsupport/src/plat/morello-qemu/serial.c new file mode 100644 index 000000000..791d5eb57 --- /dev/null +++ b/libplatsupport/src/plat/morello-qemu/serial.c @@ -0,0 +1,75 @@ +/* + * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +/* Mostly copy/paste from the HiKey plat. + * Should be moved to a common driver file for PL011 */ + +#include +#include +#include +#include "../../chardev.h" + +#define RHR_MASK MASK(8) +#define UARTDR 0x000 +#define UARTFR 0x018 +#define UARTIMSC 0x038 +#define UARTICR 0x044 +#define PL011_UARTFR_TXFF BIT(5) +#define PL011_UARTFR_RXFE BIT(4) + +#define REG_PTR(base, off) ((volatile uint32_t *)((base) + (off))) + +int uart_getchar(ps_chardevice_t *d) +{ + int ch = EOF; + + if ((*REG_PTR(d->vaddr, UARTFR) & PL011_UARTFR_RXFE) == 0) { + ch = *REG_PTR(d->vaddr, UARTDR) & RHR_MASK; + } + return ch; +} + +int uart_putchar(ps_chardevice_t *d, int c) +{ + if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { + uart_putchar(d, '\r'); + } + + while ((*REG_PTR(d->vaddr, UARTFR) & PL011_UARTFR_TXFF) != 0); + + *REG_PTR(d->vaddr, UARTDR) = c; + + return c; +} + +static void uart_handle_irq(ps_chardevice_t *dev) +{ + *REG_PTR(dev->vaddr, UARTICR) = 0x7f0; +} + +int uart_init(const struct dev_defn *defn, + const ps_io_ops_t *ops, + ps_chardevice_t *dev) +{ + memset(dev, 0, sizeof(*dev)); + void *vaddr = chardev_map(defn, ops); + if (vaddr == NULL) { + return -1; + } + + /* Set up all the device properties. */ + dev->id = defn->id; + dev->vaddr = (void *)vaddr; + dev->read = &uart_read; + dev->write = &uart_write; + dev->handle_irq = &uart_handle_irq; + dev->irqs = defn->irqs; + dev->ioops = *ops; + dev->flags = SERIAL_AUTO_CR; + + *REG_PTR(dev->vaddr, UARTIMSC) = 0x50; + return 0; +}