Skip to content

Commit 4901dc5

Browse files
committed
hello_world rig for exercising xtensa-win0
1 parent f203b65 commit 4901dc5

File tree

2 files changed

+141
-2
lines changed

2 files changed

+141
-2
lines changed

samples/hello_world/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
# nothing here
2+
CONFIG_ASSERT=y

samples/hello_world/src/main.c

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,148 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#include <stdio.h>
7+
#include <xtensa/corebits.h>
8+
#include <xtensa/config/core-isa.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/arch/syscall.h>
11+
12+
/* This choice of IRQ 11 is specific to sample_controller; we want a
13+
* software interrupt at level 2 or higher. (Note that gen_zsr.py
14+
* will pick this same interrupt for irq_offload())
15+
*/
16+
#define SWINT 11
17+
BUILD_ASSERT(XCHAL_INT11_TYPE == XTHAL_INTTYPE_SOFTWARE);
18+
BUILD_ASSERT(XCHAL_INT11_LEVEL > 1);
19+
20+
volatile int one;
21+
volatile int zero;
22+
volatile int swint_ran;
23+
volatile int timer_done;
24+
25+
struct k_thread boom;
26+
K_THREAD_STACK_DEFINE(boom_stack, 2048);
27+
28+
struct k_timer timer;
29+
30+
void *_k_syscall_table[K_SYSCALL_LIMIT];
31+
32+
int priv_stack[512];
33+
int *_mock_priv_stack = &priv_stack[ARRAY_SIZE(priv_stack)];
34+
35+
void syscall_bad(void)
36+
{
37+
printk("bad syscall!\n");
38+
}
39+
40+
int syscall_4(int a, int b, int c, int d)
41+
{
42+
printk("syscall_4 %d:%d:%d:%d\n", a, b, c, d);
43+
return 99;
44+
}
45+
46+
int do_syscall(int num, int a, int b, int c, int d)
47+
{
48+
for (int i = 0; i < K_SYSCALL_LIMIT; i++) {
49+
void *f = i == num ? (void *)syscall_4 : (void *)syscall_bad;
50+
51+
_k_syscall_table[i] = f;
52+
}
53+
return arch_syscall_invoke4(a, b, c, d, num);
54+
}
55+
56+
void syscall_fn(void *a, void *b, void *c)
57+
{
58+
printk("Starting syscall test, setting PS to user mode\n");
59+
XTENSA_WSR("PS", XTENSA_RSR("PS") | PS_UM_MASK);
60+
61+
printk("Trapping to syscall\n");
62+
int x = do_syscall(3, 12, 34, 56, 78);
63+
printk("Syscall returned %d\n", x);
64+
65+
printk("Trying invalid syscall number\n");
66+
do_syscall(20972, 0, 0, 0, 0);
67+
68+
printk("Restoring kernel mode, retrying syscall (should oops)\n");
69+
XTENSA_WSR("PS", XTENSA_RSR("PS") & ~PS_UM_MASK);
70+
do_syscall(3, 12, 34, 56, 78);
71+
72+
printk("(should not reach this line)\n");
73+
}
74+
75+
void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf)
76+
{
77+
printk("fatal error!\n");
78+
}
79+
80+
void assert_post_action(const char *f, unsigned int l) { while(1); }
81+
82+
void boom_fn(void *a, void *b, void *c)
83+
{
84+
one = 1;
85+
printk("Dividing by zero:\n");
86+
int x = one/zero;
87+
printk("1/0 = %d\n", x);
88+
}
89+
90+
void swint_isr(void *arg)
91+
{
92+
printk("swint! (nested = %d)\n", arch_curr_cpu()->nested);
93+
swint_ran = 1;
94+
}
95+
96+
void trigger_swint(void)
97+
{
98+
int val = BIT(SWINT);
99+
100+
swint_ran = 0;
101+
__asm__ volatile("wsr %0, INTSET" :: "r"(val));
102+
}
103+
104+
void timer_fn(struct k_timer *t)
105+
{
106+
printk("Timer context; triggering nested interrupt...\n");
107+
trigger_swint();
108+
while(!swint_ran);
109+
printk("Timer done\n");
110+
timer_done = 1;
111+
}
8112

9113
int main(void)
10114
{
11-
printf("Hello World! %s\n", CONFIG_BOARD);
115+
IRQ_CONNECT(SWINT, 0, swint_isr, NULL, 0);
116+
irq_enable(SWINT);
117+
118+
printk("Hello World! %s\n", CONFIG_BOARD);
119+
120+
printk("In main thread %p\n", k_current_get());
121+
k_thread_create(&boom, boom_stack, K_THREAD_STACK_SIZEOF(boom_stack),
122+
boom_fn, NULL, NULL, NULL,
123+
1, 0, K_FOREVER);
124+
125+
printk("Launching crashing thread %p\n", &boom);
126+
k_thread_start(&boom);
127+
printk("Joining crashing thread\n");
128+
k_thread_join(&boom, K_FOREVER);
129+
130+
printk("Back in main thread, sleeping for one second...\n");
131+
k_msleep(1000);
132+
printk("Still here!\n");
133+
134+
printk("Flagging medium priority interrupt\n");
135+
trigger_swint();
136+
printk("flagged, back\n");
137+
138+
printk("Triggering nested swint from timer\n");
139+
k_timer_init(&timer, timer_fn, NULL);
140+
k_timer_start(&timer, K_MSEC(1), K_FOREVER);
141+
while(!timer_done);
142+
143+
printk("Launching syscall thread %p\n", &boom);
144+
k_thread_create(&boom, boom_stack, K_THREAD_STACK_SIZEOF(boom_stack),
145+
syscall_fn, NULL, NULL, NULL,
146+
1, 0, K_NO_WAIT);
147+
k_thread_join(&boom, K_FOREVER);
148+
149+
printk("Back in main thread, end of test.\n");
12150
return 0;
13151
}

0 commit comments

Comments
 (0)