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

Port recent changes from v201908-branch to master #184

Merged
merged 4 commits into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ nobase_include_HEADERS = \
metal/drivers/riscv_clint0.h \
metal/drivers/riscv_cpu.h \
metal/drivers/riscv_plic0.h \
metal/drivers/sifive_ccache0.h \
metal/drivers/sifive_clic0.h \
metal/drivers/sifive_fe310-g000_hfrosc.h \
metal/drivers/sifive_fe310-g000_hfxosc.h \
Expand Down Expand Up @@ -164,6 +165,7 @@ libriscv__mmachine__@MACHINE_NAME@_a_SOURCES = \
src/drivers/riscv_clint0.c \
src/drivers/riscv_cpu.c \
src/drivers/riscv_plic0.c \
src/drivers/sifive_ccache0.c \
src/drivers/sifive_clic0.c \
src/drivers/sifive_fe310-g000_hfrosc.c \
src/drivers/sifive_fe310-g000_hfxosc.c \
Expand Down
21 changes: 21 additions & 0 deletions Makefile.in

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion doc/sphinx/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
copyright = '2019, SiFive Inc.'
author = 'SiFive Inc.'

version = "v201905"
version = "master"
release = version


Expand Down Expand Up @@ -72,6 +72,10 @@
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# This tells Sphinx to ignore the `__inline__` function attribute, fixing
# errors related to parsing the function signature of functions marked `__inline__`.
cpp_id_attributes = ["__inline__"]


# -- Options for HTML output -------------------------------------------------

Expand Down
22 changes: 22 additions & 0 deletions metal/drivers/sifive_ccache0.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Copyright 2019 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */

#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H
#define METAL__DRIVERS__SIFIVE_CCACHE0_H

#include <metal/cache.h>
#include <metal/compiler.h>

struct __metal_driver_vtable_sifive_ccache0 {
struct __metal_cache_vtable cache;
};

struct __metal_driver_sifive_ccache0;

__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_ccache0)

struct __metal_driver_sifive_ccache0 {
struct metal_cache cache;
};

#endif
21 changes: 20 additions & 1 deletion metal/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define METAL__LOCK_H

#include <metal/compiler.h>
#include <metal/machine.h>
#include <metal/memory.h>

/*!
Expand All @@ -15,6 +16,9 @@
/* TODO: How can we make the exception code platform-independant? */
#define _METAL_STORE_AMO_ACCESS_FAULT 7

#define METAL_LOCK_BACKOFF_CYCLES 32
#define METAL_LOCK_BACKOFF_EXPONENT 2

/*!
* @def METAL_LOCK_DECLARE
* @brief Declare a lock
Expand Down Expand Up @@ -76,11 +80,26 @@ __inline__ int metal_lock_take(struct metal_lock *lock) {
int old = 1;
int new = 1;

while (old != 0) {
int backoff = 1;
const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES;

while (1) {
__asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])"
: [old] "=r"(old)
: [new] "r"(new), [state] "r"(&(lock->_state))
: "memory");

if (old == 0) {
break;
}

for (int i = 0; i < backoff; i++) {
__asm__ volatile("");
}

if (backoff < max_backoff) {
backoff *= METAL_LOCK_BACKOFF_EXPONENT;
}
}

return 0;
Expand Down
87 changes: 87 additions & 0 deletions src/drivers/sifive_ccache0.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* Copyright 2019 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */

#include <metal/machine/platform.h>

#ifdef METAL_SIFIVE_CCACHE0

#include <metal/drivers/sifive_ccache0.h>
#include <metal/io.h>
#include <metal/machine.h>
#include <stdint.h>

#define L2_CONFIG_WAYS_SHIFT 8
#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT)

void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways);

static void metal_driver_sifive_ccache0_init(void) __attribute__((constructor));
static void metal_driver_sifive_ccache0_init(void) {
#ifdef __METAL_DT_SIFIVE_CCACHE0_HANDLE
/* Get the handle for the L2 cache controller */
struct metal_cache *l2 = __METAL_DT_SIFIVE_CCACHE0_HANDLE;
if (!l2) {
return;
}

/* Get the number of available ways per bank */
unsigned long control_base = __metal_driver_sifive_ccache0_control_base(l2);
uint32_t ways = __METAL_ACCESS_ONCE(
(__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_CONFIG));
ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT);

/* Enable all the ways */
__metal_driver_sifive_ccache0_init(l2, ways);
#endif
}

void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways) {
metal_cache_set_enabled_ways(l2, ways);
}

int __metal_driver_sifive_ccache0_get_enabled_ways(struct metal_cache *cache) {
unsigned long control_base =
__metal_driver_sifive_ccache0_control_base(cache);

uint32_t way_enable = __METAL_ACCESS_ONCE(
(__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE));

/* The stored number is the index, so add one */
return (0xFF & way_enable) + 1;
}

int __metal_driver_sifive_ccache0_set_enabled_ways(struct metal_cache *cache,
int ways) {
unsigned long control_base =
__metal_driver_sifive_ccache0_control_base(cache);

/* We can't decrease the number of enabled ways */
if (metal_cache_get_enabled_ways(cache) > ways) {
return -2;
}

/* The stored value is the index, so subtract one */
uint32_t value = 0xFF & (ways - 1);

/* Set the number of enabled ways */
__METAL_ACCESS_ONCE(
(__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)) =
value;

/* Make sure the number of ways was set correctly */
if (metal_cache_get_enabled_ways(cache) != ways) {
return -3;
}

return 0;
}

__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_ccache0) = {
.cache.init = __metal_driver_sifive_ccache0_init,
.cache.get_enabled_ways = __metal_driver_sifive_ccache0_get_enabled_ways,
.cache.set_enabled_ways = __metal_driver_sifive_ccache0_set_enabled_ways,
};

#endif

typedef int no_empty_translation_units;