| 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); |