Skip to content

Commit

Permalink
morello: Add support for QEMU platform
Browse files Browse the repository at this point in the history
This was tested on a baseline AArch64 Morello/QEMU without CHERI.
Basic support for a PL011 driver.

Signed-off-by: Hesham Almatary <[email protected]>
  • Loading branch information
heshamelmatary committed Jan 12, 2024
1 parent af6b18b commit 8b2be6c
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 0 deletions.
19 changes: 19 additions & 0 deletions libplatsupport/plat_include/morello-qemu/platsupport/plat/clock.h
Original file line number Diff line number Diff line change
@@ -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
};
11 changes: 11 additions & 0 deletions libplatsupport/plat_include/morello-qemu/platsupport/plat/i2c.h
Original file line number Diff line number Diff line change
@@ -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
};
22 changes: 22 additions & 0 deletions libplatsupport/plat_include/morello-qemu/platsupport/plat/serial.h
Original file line number Diff line number Diff line change
@@ -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
41 changes: 41 additions & 0 deletions libplatsupport/src/plat/morello-qemu/chardev.c
Original file line number Diff line number Diff line change
@@ -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 <utils/util.h>

#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;
}
75 changes: 75 additions & 0 deletions libplatsupport/src/plat/morello-qemu/serial.c
Original file line number Diff line number Diff line change
@@ -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 <string.h>
#include <stdlib.h>
#include <platsupport/serial.h>
#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;
}

0 comments on commit 8b2be6c

Please sign in to comment.