blob: ec3232b07d3937f36fc5faa9a26567aa51203fa0 [file] [log] [blame] [raw]
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 6c2c379..b395174 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -30,7 +30,8 @@ config RISCV
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select HAVE_ARCH_TRACEHOOK
-
+ select HAVE_IDE
+
config MMU
def_bool y
diff --git a/arch/riscv/include/uapi/asm/siginfo.h b/arch/riscv/include/uapi/asm/siginfo.h
index 29baf87..5db7078 100644
--- a/arch/riscv/include/uapi/asm/siginfo.h
+++ b/arch/riscv/include/uapi/asm/siginfo.h
@@ -17,7 +17,11 @@
#ifndef __ASM_SIGINFO_H
#define __ASM_SIGINFO_H
+#if __riscv_xlen == 64
#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#else
+#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
+#endif
#include <asm-generic/siginfo.h>
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 88b5810..f7f748e 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds
obj-y := cpu.o entry.o irq.o process.o ptrace.o reset.o setup.o \
sbi.o signal.o syscall_table.o sys_riscv.o time.o traps.o \
- stacktrace.o vdso.o vdso/
+ ide.o stacktrace.o vdso.o vdso/
obj-$(CONFIG_SMP) += smpboot.o smp.o
obj-$(CONFIG_SBI_CONSOLE) += sbi-con.o
diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
index cf2b496..540c379 100644
--- a/arch/riscv/kernel/irq.c
+++ b/arch/riscv/kernel/irq.c
@@ -12,6 +12,7 @@ struct plic_context {
volatile int claim;
};
+static int plic_irqs;
static DEFINE_PER_CPU(struct plic_context *, plic_context);
static DEFINE_PER_CPU(unsigned int, irq_in_progress);
@@ -37,11 +38,12 @@ static void plic_interrupt(void)
unsigned int cpu = smp_processor_id();
unsigned int irq = per_cpu(plic_context, cpu)->claim;
- BUG_ON(per_cpu(irq_in_progress, cpu) != 0);
+ // BUG_ON(per_cpu(irq_in_progress, cpu) != 0);
if (irq) {
per_cpu(irq_in_progress, cpu) = irq;
- generic_handle_irq(irq);
+ generic_handle_irq(irq - 1);
+ per_cpu(plic_context, cpu)->claim = irq;
}
}
@@ -73,19 +75,23 @@ asmlinkage void __irq_entry do_IRQ(unsigned int cause, struct pt_regs *regs)
static void plic_irq_mask(struct irq_data *d)
{
+#if 0
unsigned int cpu = smp_processor_id();
BUG_ON(d->irq != per_cpu(irq_in_progress, cpu));
+#endif
}
static void plic_irq_unmask(struct irq_data *d)
{
+#if 0
unsigned int cpu = smp_processor_id();
BUG_ON(d->irq != per_cpu(irq_in_progress, cpu));
per_cpu(plic_context, cpu)->claim = per_cpu(irq_in_progress, cpu);
per_cpu(irq_in_progress, cpu) = 0;
+#endif
}
struct irq_chip plic_irq_chip = {
@@ -97,6 +103,24 @@ struct irq_chip plic_irq_chip = {
void __init init_IRQ(void)
{
+ int irq;
+
+ /* Allocate our IRQs */
+ plic_irqs = /* config_string_u64(pdev, "ndevs") */ 32;
+ irq = irq_alloc_descs(0, 0, plic_irqs, 0);
+
+ if (irq != 0) {
+ printk("could not allocate %d PLIC IRQs at 0!\n", plic_irqs);
+ return;
+ }
+
+ for (irq = 0; irq < plic_irqs; ++irq) {
+ irq_set_chip_and_handler(irq, &plic_irq_chip, handle_simple_irq);
+ }
+
+ per_cpu(plic_context, 0) = ioremap(0x40002000, 8);
+
/* Enable software interrupts (and disable the others) */
- csr_write(sie, SIE_SSIE);
+ /* enable external interrupts */
+ csr_write(sie, SIE_SSIE | 0x200);
}
diff --git a/arch/riscv/kernel/sbi-con.c b/arch/riscv/kernel/sbi-con.c
index 10e499d..677417e 100644
--- a/arch/riscv/kernel/sbi-con.c
+++ b/arch/riscv/kernel/sbi-con.c
@@ -88,9 +88,8 @@ static int __init sbi_console_init(void)
int ret;
register_console(&sbi_console);
-
- sbi_tty_driver = tty_alloc_driver(1,
- TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
+
+ sbi_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
if (unlikely(IS_ERR(sbi_tty_driver)))
return PTR_ERR(sbi_tty_driver);
diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
index 58fbca0..9c64174 100644
--- a/arch/riscv/kernel/time.c
+++ b/arch/riscv/kernel/time.c
@@ -78,8 +78,11 @@ void __init time_init(void)
{
timebase = sbi_timebase();
lpj_fine = timebase;
+#if __riscv_xlen == 64
do_div(lpj_fine, HZ);
-
+#else
+ lpj_fine /= HZ;
+#endif
clocksource_register_hz(&riscv_clocksource, timebase);
init_clockevent();
diff --git a/arch/riscv/lib/delay.c b/arch/riscv/lib/delay.c
index 29097b6..ea9fb47 100644
--- a/arch/riscv/lib/delay.c
+++ b/arch/riscv/lib/delay.c
@@ -12,13 +12,28 @@ void __delay(unsigned long cycles)
void udelay(unsigned long usecs)
{
+#if __riscv_xlen == 64
__delay((unsigned long)(((u64)usecs * timebase) / 1000000UL));
-
+#else
+ /* XXX: inefficient */
+ uint64_t a;
+ a = (u64)usecs * timebase;
+ do_div(a, 1000000UL);
+ __delay(a);
+#endif
}
EXPORT_SYMBOL(udelay);
void ndelay(unsigned long nsecs)
{
+#if __riscv_xlen == 64
__delay((unsigned long)(((u64)nsecs * timebase) / 1000000000UL));
+#else
+ /* XXX: inefficient */
+ uint64_t a;
+ a = (u64)nsecs * timebase;
+ do_div(a, 1000000000UL);
+ __delay(a);
+#endif
}
EXPORT_SYMBOL(ndelay);