forked from deepin-community/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RISC-V: Device, timer, IRQs, and the SBI
This patch contains code that interfaces with devices that are mandated by the RISC-V supervisor specification and that don't have explicit drivers anywhere else in the tree. This includes the staticly defined interrupts, the CSR-mapped timer, and virtualized SBI devices. Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com>
- Loading branch information
1 parent
7db91e5
commit 6d60b6e
Showing
9 changed files
with
566 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com> | ||
* Copyright (C) 2016 Regents of the University of California | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#ifndef _ASM_RISCV_DELAY_H | ||
#define _ASM_RISCV_DELAY_H | ||
|
||
extern unsigned long riscv_timebase; | ||
|
||
#define udelay udelay | ||
extern void udelay(unsigned long usecs); | ||
|
||
#define ndelay ndelay | ||
extern void ndelay(unsigned long nsecs); | ||
|
||
extern void __delay(unsigned long cycles); | ||
|
||
#endif /* _ASM_RISCV_DELAY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (C) 2003-2004 Hewlett-Packard Co | ||
* David Mosberger-Tang <davidm@hpl.hp.com> | ||
* Copyright (C) 2012 ARM Ltd. | ||
* Copyright (C) 2016 SiFive, Inc. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
#ifndef __ASM_RISCV_DMA_MAPPING_H | ||
#define __ASM_RISCV_DMA_MAPPING_H | ||
|
||
/* Use ops->dma_mapping_error (if it exists) or assume success */ | ||
// #undef DMA_ERROR_CODE | ||
|
||
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) | ||
{ | ||
return &dma_noop_ops; | ||
} | ||
|
||
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | ||
{ | ||
if (!dev->dma_mask) | ||
return false; | ||
|
||
return addr + size - 1 <= *dev->dma_mask; | ||
} | ||
|
||
#endif /* __ASM_RISCV_DMA_MAPPING_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (C) 2012 Regents of the University of California | ||
* Copyright (C) 2017 SiFive | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#ifndef _ASM_RISCV_IRQ_H | ||
#define _ASM_RISCV_IRQ_H | ||
|
||
#define NR_IRQS 0 | ||
|
||
#define INTERRUPT_CAUSE_SOFTWARE 1 | ||
#define INTERRUPT_CAUSE_TIMER 5 | ||
#define INTERRUPT_CAUSE_EXTERNAL 9 | ||
|
||
void riscv_timer_interrupt(void); | ||
|
||
#include <asm-generic/irq.h> | ||
|
||
#endif /* _ASM_RISCV_IRQ_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright (C) 2012 Regents of the University of California | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
|
||
#ifndef _ASM_RISCV_IRQFLAGS_H | ||
#define _ASM_RISCV_IRQFLAGS_H | ||
|
||
#include <asm/processor.h> | ||
#include <asm/csr.h> | ||
|
||
/* read interrupt enabled status */ | ||
static inline unsigned long arch_local_save_flags(void) | ||
{ | ||
return csr_read(sstatus); | ||
} | ||
|
||
/* unconditionally enable interrupts */ | ||
static inline void arch_local_irq_enable(void) | ||
{ | ||
csr_set(sstatus, SR_IE); | ||
} | ||
|
||
/* unconditionally disable interrupts */ | ||
static inline void arch_local_irq_disable(void) | ||
{ | ||
csr_clear(sstatus, SR_IE); | ||
} | ||
|
||
/* get status and disable interrupts */ | ||
static inline unsigned long arch_local_irq_save(void) | ||
{ | ||
return csr_read_clear(sstatus, SR_IE); | ||
} | ||
|
||
/* test flags */ | ||
static inline int arch_irqs_disabled_flags(unsigned long flags) | ||
{ | ||
return !(flags & SR_IE); | ||
} | ||
|
||
/* test hardware interrupt enable bit */ | ||
static inline int arch_irqs_disabled(void) | ||
{ | ||
return arch_irqs_disabled_flags(arch_local_save_flags()); | ||
} | ||
|
||
/* set interrupt enabled status */ | ||
static inline void arch_local_irq_restore(unsigned long flags) | ||
{ | ||
csr_set(sstatus, flags & SR_IE); | ||
} | ||
|
||
#endif /* _ASM_RISCV_IRQFLAGS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (C) 2016 SiFive | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#ifndef __ASM_RISCV_PCI_H | ||
#define __ASM_RISCV_PCI_H | ||
|
||
#include <linux/types.h> | ||
#include <linux/slab.h> | ||
#include <linux/dma-mapping.h> | ||
|
||
#include <asm/io.h> | ||
|
||
#define PCIBIOS_MIN_IO 0 | ||
#define PCIBIOS_MIN_MEM 0 | ||
|
||
/* RISC-V shim does not initialize PCI bus */ | ||
#define pcibios_assign_all_busses() 1 | ||
|
||
/* We do not have an IOMMU */ | ||
#define PCI_DMA_BUS_IS_PHYS 1 | ||
|
||
extern int isa_dma_bridge_buggy; | ||
|
||
#ifdef CONFIG_PCI | ||
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | ||
{ | ||
/* no legacy IRQ on risc-v */ | ||
return -ENODEV; | ||
} | ||
|
||
static inline int pci_proc_domain(struct pci_bus *bus) | ||
{ | ||
/* always show the domain in /proc */ | ||
return 1; | ||
} | ||
#endif /* CONFIG_PCI */ | ||
|
||
#endif /* __ASM_PCI_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (C) 2015 Regents of the University of California | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#ifndef _ASM_RISCV_SBI_H | ||
#define _ASM_RISCV_SBI_H | ||
|
||
#include <linux/types.h> | ||
|
||
#define SBI_SET_TIMER 0 | ||
#define SBI_CONSOLE_PUTCHAR 1 | ||
#define SBI_CONSOLE_GETCHAR 2 | ||
#define SBI_CLEAR_IPI 3 | ||
#define SBI_SEND_IPI 4 | ||
#define SBI_REMOTE_FENCE_I 5 | ||
#define SBI_REMOTE_SFENCE_VMA 6 | ||
#define SBI_REMOTE_SFENCE_VMA_ASID 7 | ||
#define SBI_SHUTDOWN 8 | ||
|
||
#define SBI_CALL(which, arg0, arg1, arg2) ({ \ | ||
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ | ||
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ | ||
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ | ||
register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ | ||
asm volatile ("ecall" \ | ||
: "+r" (a0) \ | ||
: "r" (a1), "r" (a2), "r" (a7) \ | ||
: "memory"); \ | ||
a0; \ | ||
}) | ||
|
||
/* Lazy implementations until SBI is finalized */ | ||
#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) | ||
#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) | ||
#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0) | ||
|
||
static inline void sbi_console_putchar(int ch) | ||
{ | ||
SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); | ||
} | ||
|
||
static inline int sbi_console_getchar(void) | ||
{ | ||
return SBI_CALL_0(SBI_CONSOLE_GETCHAR); | ||
} | ||
|
||
static inline void sbi_set_timer(uint64_t stime_value) | ||
{ | ||
#if __riscv_xlen == 32 | ||
SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); | ||
#else | ||
SBI_CALL_1(SBI_SET_TIMER, stime_value); | ||
#endif | ||
} | ||
|
||
static inline void sbi_shutdown(void) | ||
{ | ||
SBI_CALL_0(SBI_SHUTDOWN); | ||
} | ||
|
||
static inline void sbi_clear_ipi(void) | ||
{ | ||
SBI_CALL_0(SBI_CLEAR_IPI); | ||
} | ||
|
||
static inline void sbi_send_ipi(const unsigned long *hart_mask) | ||
{ | ||
SBI_CALL_1(SBI_SEND_IPI, hart_mask); | ||
} | ||
|
||
static inline void sbi_remote_fence_i(const unsigned long *hart_mask) | ||
{ | ||
SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); | ||
} | ||
|
||
static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, | ||
unsigned long start, | ||
unsigned long size) | ||
{ | ||
SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); | ||
} | ||
|
||
static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, | ||
unsigned long start, | ||
unsigned long size, | ||
unsigned long asid) | ||
{ | ||
SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Copyright (C) 2012 Regents of the University of California | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation, version 2. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
*/ | ||
|
||
#ifndef _ASM_RISCV_TIMEX_H | ||
#define _ASM_RISCV_TIMEX_H | ||
|
||
#include <asm/param.h> | ||
|
||
typedef unsigned long cycles_t; | ||
|
||
static inline cycles_t get_cycles(void) | ||
{ | ||
cycles_t n; | ||
|
||
__asm__ __volatile__ ( | ||
"rdtime %0" | ||
: "=r" (n)); | ||
return n; | ||
} | ||
|
||
#ifdef CONFIG_64BIT | ||
static inline uint64_t get_cycles64(void) | ||
{ | ||
return get_cycles(); | ||
} | ||
#else | ||
static inline uint64_t get_cycles64(void) | ||
{ | ||
u32 lo, hi, tmp; | ||
__asm__ __volatile__ ( | ||
"1:\n" | ||
"rdtimeh %0\n" | ||
"rdtime %1\n" | ||
"rdtimeh %2\n" | ||
"bne %0, %2, 1b" | ||
: "=&r" (hi), "=&r" (lo), "=&r" (tmp)); | ||
return ((u64)hi << 32) | lo; | ||
} | ||
#endif | ||
|
||
#define ARCH_HAS_READ_CURRENT_TIMER | ||
|
||
static inline int read_current_timer(unsigned long *timer_val) | ||
{ | ||
*timer_val = get_cycles(); | ||
return 0; | ||
} | ||
|
||
#endif /* _ASM_RISCV_TIMEX_H */ |
Oops, something went wrong.