Skip to content

Commit

Permalink
Merge pull request #184 from sifive/port-1908-to-master
Browse files Browse the repository at this point in the history
Port recent changes from v201908-branch to master
  • Loading branch information
nategraff-sifive authored Sep 19, 2019
2 parents 4c15078 + b36c47e commit 1f1a9ac
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 2 deletions.
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;

0 comments on commit 1f1a9ac

Please sign in to comment.