Skip to content

Commit de5b5c0

Browse files
committed
machine/qemu: riscv32 virt board
Change-Id: I48be009b4c7aa239d90f7c1e35d880f4743190fe
1 parent ee26407 commit de5b5c0

File tree

6 files changed

+243
-0
lines changed

6 files changed

+243
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SOURCES += \
2+
$(CONFIG_MACHINEDIR)/boot/machine.cpp \
3+
$(CONFIG_MACHINEDIR)/boot/ns16550/ns16550.cpp
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <machine.h>
2+
3+
#include "ns16550/ns16550.h"
4+
#include <boot.h>
5+
6+
/*
7+
* NS16550 compatible UART at physical address 0x10000000.
8+
*/
9+
void *const UART = reinterpret_cast<void *>(0x10000000);
10+
11+
/*
12+
* Setup machine state
13+
*/
14+
void
15+
machine_setup()
16+
{
17+
/* QEMU doesn't require setup */
18+
}
19+
20+
/*
21+
* Load kernel image
22+
*/
23+
int
24+
machine_load_image()
25+
{
26+
return load_bootimg();
27+
}
28+
29+
/*
30+
* Panic handler
31+
*/
32+
[[noreturn]] void
33+
machine_panic()
34+
{
35+
/* Workaround for ancient clang bug. Looks like this will be fixed
36+
* in clang 12, https://reviews.llvm.org/D85393 */
37+
while (1) asm("");
38+
}
39+
40+
/*
41+
* Configure boot console
42+
*/
43+
void
44+
boot_console_init()
45+
{
46+
serial::ns16550::early_init(UART, 0, CONFIG_EARLY_CONSOLE_CFLAG);
47+
}
48+
49+
/*
50+
* Print a string
51+
*/
52+
void
53+
boot_console_print(const char *s, size_t len)
54+
{
55+
serial::ns16550::early_print(UART, s, len);
56+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../../sys/dev/serial/ns16550
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Kernel
3+
*/
4+
#ifdef CONFIG_MMU
5+
memory PAGE_OFFSET 0x80000000
6+
#else
7+
memory PAGE_OFFSET 0x00000000
8+
#endif
9+
memory KSTACK_SIZE 8192 // Kernel stack size
10+
option TIME_SLICE_MS 50 // milliseconds
11+
option HZ 1000
12+
option PAGE_SIZE 0x1000
13+
option IRQS 53 // External interrupts
14+
option MA_NORMAL_ATTR (MA_SPEED_0) // Normal allocations in DRAM
15+
option MA_FAST_ATTR (MA_SPEED_0) // Fast allocations in DRAM
16+
17+
/*
18+
* RAM
19+
*/
20+
memory RAM_BASE 0x80000000
21+
memory RAM_SIZE 0x8000000
22+
23+
/*
24+
* QEMU loads boot image at start of RAM when using -bios option.
25+
* Allow up to 16MiB image.
26+
* Place loader data at end of RAM.
27+
*/
28+
memory BOOTIMAGE_SIZE 0x1000000
29+
memory BOOTIMAGE_BASE (CONFIG_RAM_BASE_VIRT)
30+
memory LOADER_RAM_SIZE 0x2000
31+
memory LOADER_RAM_BASE (CONFIG_RAM_BASE_VIRT + CONFIG_RAM_SIZE - CONFIG_LOADER_RAM_SIZE)
32+
33+
/*
34+
* Load kernel after boot image.
35+
* Allow up to 16MiB image.
36+
*/
37+
memory KERNEL_BASE (CONFIG_RAM_BASE_VIRT + CONFIG_BOOTIMAGE_SIZE)
38+
memory KERNEL_MAX_SIZE 0x1000000
39+
40+
/*
41+
* Device drivers
42+
*/
43+
driver-2 sys/dev/intc/sifive/clint{.base = 0x02000000_phys, .clock = 10000000}
44+
driver-1 sys/dev/intc/sifive/plic{.base = 0x0c000000_phys}
45+
driver sys/dev/serial/ns16550{.name = "ttyS0", .base = 0x10000000_phys, .ipl = IPL_MIN, .irq = 10, .irq_mode = 0}
46+
47+
/*
48+
* QEMU command line
49+
*/
50+
makeoption QEMU_IMG := bootimg
51+
makeoption QEMU_CMD := qemu-system-riscv32 -nographic -machine virt -cpu $(CONFIG_QEMU_CPU) -bios
52+
53+
/*
54+
* Pretty machine name
55+
*/
56+
option MACHINE_NAME QEMU RISC-V 32-bit virt
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LDSCRIPT := arch/$(CONFIG_ARCH)/kernel.ld
2+
3+
SOURCES += \
4+
$(CONFIG_MACHINEDIR)/sys/machine.cpp
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include <arch/early_console.h>
2+
#include <arch/machine.h>
3+
4+
#include <arch/mmio.h>
5+
#include <arch/mmu.h>
6+
#include <compiler.h>
7+
#include <conf/config.h>
8+
#include <conf/drivers.h>
9+
#include <cpu.h>
10+
#include <debug.h>
11+
#include <dev/intc/sifive/clint/clint.h>
12+
#include <dev/intc/sifive/plic/plic.h>
13+
#include <dev/serial/ns16550/ns16550.h>
14+
#include <intrinsics.h>
15+
#include <locore.h>
16+
#include <page.h>
17+
#include <sch.h>
18+
#include <sections.h>
19+
#include <thread.h>
20+
#include <types.h>
21+
22+
constexpr auto UART = 0x10000000_phys;
23+
24+
void
25+
machine_init(bootargs *args)
26+
{
27+
#ifdef CONFIG_MPU
28+
mpu_init(nullptr, 0, 0);
29+
#endif
30+
31+
const meminfo memory[] = {
32+
/* Main memory */
33+
{
34+
.base = phys{CONFIG_RAM_BASE_PHYS},
35+
.size = CONFIG_RAM_SIZE,
36+
.attr = MA_SPEED_0,
37+
.priority = 0,
38+
},
39+
};
40+
page_init(memory, ARRAY_SIZE(memory), args);
41+
42+
/* scratch register is 0 in kernel mode */
43+
#ifdef CONFIG_S_MODE
44+
csrw(sscratch{});
45+
#else
46+
csrw(mscratch{});
47+
#endif
48+
/* initialise kernel thread pointer */
49+
asm volatile("mv tp, %0" : : "r"(thread_cur()));
50+
}
51+
52+
void
53+
machine_driver_init(bootargs *bootargs)
54+
{
55+
/*
56+
* Run driver initialisation
57+
*/
58+
#include <conf/drivers.c>
59+
}
60+
61+
void
62+
machine_idle()
63+
{
64+
asm("wfi");
65+
}
66+
67+
[[noreturn]] void
68+
machine_reset()
69+
{
70+
write32(reinterpret_cast<int *>(0x100000), 0x7777);
71+
72+
/* Workaround clang bug. */
73+
while (1) asm("");
74+
}
75+
76+
void
77+
machine_poweroff()
78+
{
79+
write32(reinterpret_cast<int *>(0x100000), 0x5555);
80+
81+
/* Workaround clang bug. */
82+
while (1) asm("");
83+
}
84+
85+
void
86+
machine_suspend()
87+
{
88+
info("Suspend is not supported on this platform.\n");
89+
}
90+
91+
[[noreturn]] void
92+
machine_panic()
93+
{
94+
/* Workaround clang bug. */
95+
while (1) asm("");
96+
}
97+
98+
void
99+
early_console_init()
100+
{
101+
/* QEMU doesn't care about baud rate */
102+
serial::ns16550::early_init(phys_to_virt(UART), 0, CONFIG_EARLY_CONSOLE_CFLAG);
103+
}
104+
105+
void
106+
early_console_print(const char *s, size_t len)
107+
{
108+
serial::ns16550::early_print(phys_to_virt(UART), s, len);
109+
}
110+
111+
__fast_text
112+
void
113+
machine_irq()
114+
{
115+
intc_sifive_plic_irq();
116+
}
117+
118+
__fast_text
119+
void
120+
machine_timer()
121+
{
122+
intc_sifive_clint_timer_irq();
123+
}

0 commit comments

Comments
 (0)