Skip to content

Commit abdeee5

Browse files
committed
arch: Added initial OpenRISC architecture port
This patch adds support for the OpenRISC 1000 (or1k) architecture: a MIPS-like open hardware ISA which was first introduced in 2000. The thread switching implementation uses the modern Zephyr thread "switch" architecture. Signed-off-by: Joel Holdsworth <jholdsworth@nvidia.com>
1 parent a7d79ab commit abdeee5

32 files changed

+2595
-1
lines changed

MAINTAINERS.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5569,3 +5569,15 @@ zbus:
55695569
- "area: llext"
55705570
tests:
55715571
- llext
5572+
5573+
OpenRISC Arch:
5574+
status: maintained
5575+
maintainers:
5576+
- jhol
5577+
files:
5578+
- arch/openrisc/
5579+
- include/zephyr/arch/openrisc/
5580+
labels:
5581+
- "area: OpenRISC"
5582+
tests:
5583+
- arch.openrisc

arch/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ config MIPS
6666
help
6767
MIPS architecture
6868

69+
config OPENRISC
70+
bool
71+
select ARCH_IS_SET
72+
select ATOMIC_OPERATIONS_BUILTIN
73+
select BIG_ENDIAN
74+
select USE_SWITCH
75+
select USE_SWITCH_SUPPORTED
76+
help
77+
OpenRISC architecture
78+
6979
config SPARC
7080
bool
7181
select ARCH_IS_SET

arch/archs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ archs:
99
path: mips
1010
- name: nios2
1111
path: nios2
12+
- name: openrisc
13+
path: openrisc
1214
- name: posix
1315
path: posix
1416
- name: riscv

arch/openrisc/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com>
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT "elf32-or1k")
8+
9+
add_subdirectory(core)
10+
zephyr_include_directories(include)

arch/openrisc/Kconfig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#
2+
# Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com>
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
menu "OpenRISC Options"
8+
depends on OPENRISC
9+
10+
config ARCH
11+
string
12+
default "openrisc"
13+
14+
config GEN_ISR_TABLES
15+
default y
16+
17+
config GEN_IRQ_VECTOR_TABLE
18+
default n
19+
20+
config GEN_SW_ISR_TABLE
21+
default y
22+
23+
config NUM_IRQS
24+
int
25+
26+
endmenu

arch/openrisc/core/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com>
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
zephyr_library()
8+
9+
zephyr_library_sources(
10+
cpu_idle.c
11+
fatal.c
12+
irq_manage.c
13+
isr.S
14+
prep_c.c
15+
reboot.c
16+
switch.S
17+
thread.c
18+
)
19+
20+
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)

arch/openrisc/core/asm_macros.inc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2025 NVIDIA Corporation
3+
*
4+
* Convenience macros for assembly code
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
/* Convenience macros for assembly code. */
10+
11+
12+
/*
13+
* Helper macro which stores the value of a register to a the address contained
14+
* in a pointer register plus an immediate offset.
15+
*/
16+
17+
.macro op_store_reg reg, off, ptr_reg
18+
l.sw \off(\ptr_reg), \reg
19+
.endm
20+
21+
22+
/*
23+
* Helper macro which load a value to a register from an address contained in a
24+
* pointer register plus an immediate offset.
25+
*/
26+
27+
.macro op_load_reg reg, off, ptr_reg
28+
l.lwz \reg, \off(\ptr_reg)
29+
.endm

arch/openrisc/core/cpu_idle.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/irq.h>
8+
9+
#include <zephyr/tracing/tracing.h>
10+
11+
#include <openrisc/openriscregs.h>
12+
13+
static ALWAYS_INLINE void openrisc_idle(unsigned int key)
14+
{
15+
sys_trace_idle();
16+
17+
/* unlock interrupts */
18+
irq_unlock(key);
19+
20+
/* wait for interrupt */
21+
if (openrisc_read_spr(SPR_UPR) & SPR_UPR_PMP) {
22+
openrisc_write_spr(SPR_PMR, openrisc_read_spr(SPR_PMR) | SPR_PMR_DME);
23+
}
24+
}
25+
26+
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
27+
void arch_cpu_idle(void)
28+
{
29+
openrisc_idle(1);
30+
}
31+
#endif
32+
33+
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
34+
void arch_cpu_atomic_idle(unsigned int key)
35+
{
36+
openrisc_idle(key);
37+
}
38+
#endif

arch/openrisc/core/fatal.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com> *
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/logging/log.h>
9+
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
10+
11+
FUNC_NORETURN void z_openrisc_fatal_error(unsigned int reason,
12+
const struct arch_esf *esf)
13+
{
14+
#ifdef CONFIG_EXCEPTION_DEBUG
15+
if (esf != NULL) {
16+
LOG_ERR("epcr: 0x%08x esr: 0x%08x", esf->epcr, esf->esr);
17+
LOG_ERR(" r3: 0x%08x r4: 0x%08x r5: 0x%08x r6: 0x%08x",
18+
esf->r3, esf->r4, esf->r5, esf->r6);
19+
LOG_ERR(" r7: 0x%08x r8: 0x%08x",
20+
esf->r7, esf->r8);
21+
LOG_ERR(" r11: 0x%08x r12: 0x%08x",
22+
esf->r11, esf->r12);
23+
LOG_ERR(" r13: 0x%08x r15: 0x%08x r17: 0x%08x r19: 0x%08x",
24+
esf->r13, esf->r15, esf->r17, esf->r19);
25+
LOG_ERR(" r21: 0x%08x r23: 0x%08x r25: 0x%08x r27: 0x%08x",
26+
esf->r21, esf->r23, esf->r25, esf->r27);
27+
LOG_ERR(" r29: 0x%08x r31: 0x%08x",
28+
esf->r29, esf->r31);
29+
}
30+
#endif /* CONFIG_EXCEPTION_DEBUG */
31+
z_fatal_error(reason, esf);
32+
CODE_UNREACHABLE;
33+
}
34+
35+
static char *reason_str(unsigned int reason)
36+
{
37+
switch (reason) {
38+
case 0x2:
39+
return "Bus Error";
40+
case 0x3:
41+
return "Data Page Fault";
42+
case 0x4:
43+
return "Instruction Page Fault";
44+
case 0x5:
45+
return "Tick Timer";
46+
case 0x6:
47+
return "Alignment Exception";
48+
case 0x7:
49+
return "Illegal Instruction";
50+
case 0x8:
51+
return "External Interrupt";
52+
case 0x9:
53+
return "D-TLB Miss";
54+
case 0xA:
55+
return "I-TLB Miss";
56+
case 0xB:
57+
return "Range Exception";
58+
case 0xC:
59+
return "Syscall";
60+
case 0xD:
61+
return "Floating Point Exception";
62+
case 0xE:
63+
return "Trap";
64+
default:
65+
return "unknown";
66+
}
67+
}
68+
69+
void _Fault(struct arch_esf *esf, unsigned int reason)
70+
{
71+
LOG_ERR("");
72+
LOG_ERR(" reason: %d, %s", reason, reason_str(reason));
73+
74+
z_openrisc_fatal_error(K_ERR_CPU_EXCEPTION, esf);
75+
}

arch/openrisc/core/irq_manage.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2025 NVIDIA Corporation <jholdsworth@nvidia.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/logging/log.h>
9+
10+
#include <kswap.h>
11+
12+
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
13+
14+
15+
FUNC_NORETURN void z_irq_spurious(const void *unused)
16+
{
17+
ARG_UNUSED(unused);
18+
19+
LOG_ERR("Spurious interrupt detected!");
20+
21+
z_openrisc_fatal_error(K_ERR_SPURIOUS_IRQ, NULL);
22+
}
23+
24+
void arch_irq_enable(unsigned int irq)
25+
{
26+
const unsigned int key = irq_lock();
27+
28+
openrisc_write_spr(SPR_PICMR, openrisc_read_spr(SPR_PICMR) | BIT(irq));
29+
irq_unlock(key);
30+
}
31+
32+
void arch_irq_disable(unsigned int irq)
33+
{
34+
const unsigned int key = irq_lock();
35+
36+
openrisc_write_spr(SPR_PICMR, openrisc_read_spr(SPR_PICMR) & ~BIT(irq));
37+
irq_unlock(key);
38+
};
39+
40+
int arch_irq_is_enabled(unsigned int irq)
41+
{
42+
return (openrisc_read_spr(SPR_PICMR) & BIT(irq)) != 0;
43+
}
44+
45+
void z_openrisc_enter_irq(unsigned int irq)
46+
{
47+
if (IS_ENABLED(CONFIG_TRACING_ISR)) {
48+
sys_trace_isr_enter();
49+
}
50+
51+
const struct _isr_table_entry *const ite = _sw_isr_table + irq;
52+
53+
ite->isr(ite->arg);
54+
55+
if (IS_ENABLED(CONFIG_TRACING_ISR)) {
56+
sys_trace_isr_exit();
57+
}
58+
}
59+
60+
#ifdef CONFIG_DYNAMIC_INTERRUPTS
61+
int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
62+
void (*routine)(const void *parameter),
63+
const void *parameter, uint32_t flags)
64+
{
65+
ARG_UNUSED(flags);
66+
ARG_UNUSED(priority);
67+
68+
z_isr_install(irq, routine, parameter);
69+
return irq;
70+
}
71+
#endif /* CONFIG_DYNAMIC_INTERRUPTS */

0 commit comments

Comments
 (0)