1// Copyright © 2020-2021 Sören Tempel
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU Affero General Public License as
5// published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11// Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16const console = @import("console.zig");
17const periph = @import("periph.zig");
18const main = @import("main.zig");
19const StackTrace = @import("std").builtin.StackTrace;
20
21// Bitmasks for modifying mcause CSR
22const MCAUSE_EXPCODE = 0x0fff;
23const MCAUSE_INT = 0x80000000;
24
25// Exception codes
26const EXP_BREAKPOINT = 3;
27
28pub fn panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn {
29 _ = error_return_trace; // unused
30
31 // Copied from the default_panic implementation
32 @setCold(true);
33
34 // Write panic message, unbuffered to standard out
35 console.print("PANIC: {s}\n", .{msg});
36
37 @breakpoint();
38 while (true) {}
39}
40
41export fn level1IRQHandler() void {
42 const mcause = asm ("csrr %[ret], mcause"
43 : [ret] "=r" (-> u32)
44 );
45
46 const expcode: u32 = mcause & MCAUSE_EXPCODE;
47 if ((mcause & MCAUSE_INT) == MCAUSE_INT) {
48 periph.plic0.invokeHandler();
49 } else {
50 if (expcode == EXP_BREAKPOINT) {
51 while (true) {}
52 }
53 @panic("unexpected trap");
54 }
55}
56
57export fn init() void {
58 periph.init();
59 console.print("Booting zig-riscv-embedded...\n", .{});
60
61 main.main() catch |err| {
62 @panic(@errorName(err));
63 };
64}