opensbi/platform/common/irqchip/plic.c
Atish Patra 00f77d9ba0 platform: Remove string functions from tinyfdt.c
There are couple of string function defined in platform
code. We no longer need them as we can directly link minimal
libc.

Every platform required to inclde this as PLIC driver required
libc functions.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
2019-01-18 10:05:12 +05:30

121 lines
2.5 KiB
C

/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <sbi/riscv_io.h>
#include <plat/tinyfdt.h>
#include <plat/irqchip/plic.h>
#include <string.h>
#define PLIC_PRIORITY_BASE 0x0
#define PLIC_PENDING_BASE 0x1000
#define PLIC_ENABLE_BASE 0x2000
#define PLIC_ENABLE_STRIDE 0x80
#define PLIC_CONTEXT_BASE 0x200000
#define PLIC_CONTEXT_STRIDE 0x1000
static u32 plic_hart_count;
static u32 plic_num_sources;
static volatile void *plic_base;
static void plic_set_priority(u32 source, u32 val)
{
writel(val, plic_base);
}
static void plic_set_thresh(u32 cntxid, u32 val)
{
volatile void *plic_thresh = plic_base +
PLIC_CONTEXT_BASE +
PLIC_CONTEXT_STRIDE * cntxid;
writel(val, plic_thresh);
}
static void plic_set_ie(u32 cntxid, u32 word_index, u32 val)
{
volatile void *plic_ie = plic_base +
PLIC_ENABLE_BASE +
PLIC_ENABLE_STRIDE * cntxid;
writel(val, plic_ie + word_index * 4);
}
static void plic_fdt_fixup_prop(const struct fdt_node *node,
const struct fdt_prop *prop,
void *priv)
{
u32 *cells;
u32 i, cells_count;
u32 *cntx_id = priv;
if (!prop)
return;
if (strcmp(prop->name, "interrupts-extended"))
return;
cells = prop->value;
cells_count = prop->len / sizeof(u32);
if (!cells_count)
return;
for (i = 0; i < cells_count; i++) {
if (((i % 2) == 1) && ((i / 2) == *cntx_id))
cells[i] = fdt_rev32(0xffffffff);
}
}
void plic_fdt_fixup(void *fdt, const char *compat, u32 cntx_id)
{
fdt_compat_node_prop(fdt, compat, plic_fdt_fixup_prop, &cntx_id);
}
int plic_warm_irqchip_init(u32 target_hart,
int m_cntx_id, int s_cntx_id)
{
size_t i, ie_words = plic_num_sources / 32 + 1;
if (plic_hart_count <= target_hart)
return -1;
if (m_cntx_id > -1) {
for (i = 0; i < ie_words; i++)
plic_set_ie(m_cntx_id, i, 0);
}
/* By default, enable all IRQs for S-mode of target HART */
if (s_cntx_id > -1) {
for (i = 0; i < ie_words; i++)
plic_set_ie(s_cntx_id, i, 0);
}
/* By default, enable M-mode threshold */
if (m_cntx_id > -1)
plic_set_thresh(m_cntx_id, 1);
/* By default, disable S-mode threshold */
if (s_cntx_id > -1)
plic_set_thresh(s_cntx_id, 0);
return 0;
}
int plic_cold_irqchip_init(unsigned long base,
u32 num_sources, u32 hart_count)
{
int i;
plic_hart_count = hart_count;
plic_num_sources = num_sources;
plic_base = (void *)base;
/* Configure default priorities of all IRQs */
for (i = 0; i < plic_num_sources; i++)
plic_set_priority(i, 1);
return 0;
}