Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pine64 star64 platform #167

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions libplatsupport/plat_include/star64/platsupport/plat/serial.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2023, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once
#include <autoconf.h>

/* The StarFive JH7110 SoC contains five 8250 compatible UARTs. */

enum chardev_id {
UART0,
UART1,
UART2,
UART3,
UART4,
UART5,
PS_SERIAL_DEFAULT = UART0
};

#define UART0_PADDR 0x10000000
#define UART1_PADDR 0x10010000
#define UART2_PADDR 0x10020000
#define UART3_PADDR 0x12000000
#define UART4_PADDR 0x12010000
#define UART5_PADDR 0x12020000

#define UART0_IRQ 32
#define UART1_IRQ 33
#define UART2_IRQ 34
#define UART3_IRQ 45
#define UART4_IRQ 46
#define UART5_IRQ 47

/* The default serial device corresponds to the UART available via the GPIO
* pins of the Star64 Model-A. */
#define DEFAULT_SERIAL_PADDR UART0_PADDR
#define DEFAULT_SERIAL_INTERRUPT UART0_IRQ
71 changes: 71 additions & 0 deletions libplatsupport/plat_include/star64/platsupport/plat/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2023, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once

#include <stdint.h>
#include <stdbool.h>

/*
* The JH7110 SoC contains a timer with four 32-bit counters. Each one of these
* counters is referred to as a "channel".
*/

/* Channel information */
#define STARFIVE_TIMER_NUM_CHANNELS 4
#define STARFIVE_TIMER_CHANNEL_REGISTERS_LEN_IN_BYTES 0x40
#define STARFIVE_TIMER_CHANNEL_0_IRQ 69
#define STARFIVE_TIMER_CHANNEL_1_IRQ 70
#define STARFIVE_TIMER_CHANNEL_2_IRQ 71
#define STARFIVE_TIMER_CHANNEL_3_IRQ 72

/* This information comes from the DTS file */
#define STARFIVE_TIMER_BASE 0x13050000
#define STARFIVE_TIMER_REGISTER_WINDOW_LEN_IN_BYTES 0x10000
#define STARFIVE_TIMER_TICKS_PER_SECOND 0x16e3600
Ivan-Velickovic marked this conversation as resolved.
Show resolved Hide resolved

#define STARFIVE_TIMER_MAX_TICKS 0xffffffff
Ivan-Velickovic marked this conversation as resolved.
Show resolved Hide resolved

/* Register value constants */
#define STARFIVE_TIMER_MODE_CONTINUOUS 0
#define STARFIVE_TIMER_MODE_SINGLE 1
#define STARFIVE_TIMER_DISABLED 0
#define STARFIVE_TIMER_ENABLED 1
#define STARFIVE_TIMER_INTERRUPT_UNMASKED 0
#define STARFIVE_TIMER_INTERRUPT_MASKED 1
#define STARFIVE_TIMER_INTCLR_BUSY BIT(1)

typedef struct {
/* Registers */
/* this register doesn't seem to do anything */
uint32_t status;
uint32_t ctrl;
uint32_t load;
uint32_t unknown1;
uint32_t enable;
uint32_t reload;
uint32_t value;
uint32_t unknown2;
uint32_t intclr;
uint32_t intmask;
} starfive_timer_regs_t;

typedef struct {
volatile starfive_timer_regs_t *regs;
/*
* Stores the number of times the continuous counter timer has elapsed and started over.
* This allows us to count to a higher number than allowed by the hardware.
*/
uint32_t value_h;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be declared volatile also, as it could be access concurrently, and we also want to prevent the compiler from doing some optimization that would move the accesses around.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, these drivers aren't multithreaded right? How could there be concurrent access?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Driver ware not multi-threaded, but they have an ISR that could interrupt us any time and update this value. Using volatile might not prevent the race completely, but could makes the windows even smaller.

} starfive_timer_t;

void starfive_timer_start(starfive_timer_t *timer);
void starfive_timer_stop(starfive_timer_t *timer);
void starfive_timer_handle_irq(starfive_timer_t *timer);
uint64_t starfive_timer_get_time(starfive_timer_t *timer);
void starfive_timer_reset(starfive_timer_t *timer);
int starfive_timer_set_timeout(starfive_timer_t *timer, uint64_t ns, bool is_periodic);
void starfive_timer_disable_all_channels(void *vaddr);
void starfive_timer_init(starfive_timer_t *timer, void *vaddr, uint64_t channel);
49 changes: 49 additions & 0 deletions libplatsupport/src/plat/star64/chardev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2023, UNSW
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include "../../chardev.h"
#include "../../common.h"
#include <utils/util.h>

static const int uart0_irqs[] = {UART0_IRQ, -1};
static const int uart1_irqs[] = {UART1_IRQ, -1};
static const int uart2_irqs[] = {UART2_IRQ, -1};
static const int uart3_irqs[] = {UART3_IRQ, -1};
static const int uart4_irqs[] = {UART4_IRQ, -1};
static const int uart5_irqs[] = {UART5_IRQ, -1};

/*
* Despite each UART being 0x10000 in size (according to the device tree) we
* only need to map in the first page for the driver to functon.
*/
#define UART_DEFN(devid) { \
.id = UART##devid, \
.paddr = UART##devid##_PADDR, \
.size = BIT(12), \
.irqs = uart##devid##_irqs, \
.init_fn = &uart_init \
}

const struct dev_defn dev_defn[] = {
UART_DEFN(0),
UART_DEFN(1),
UART_DEFN(2),
UART_DEFN(3),
UART_DEFN(4),
UART_DEFN(5),
};

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;
}
Loading