Add ESP32C3 RISC-V stub
diff --git a/bin/jmk2 b/bin/jmk2
index 4bb9e1c..186344c 100755
--- a/bin/jmk2
+++ b/bin/jmk2
@@ -36,7 +36,7 @@
set ld {$ld}
set asm {$asm}
set root {$root}
-set jmk_build_cmd {$0}
+set jmk_build_cmd {$0 $*}
set jmk_build_dir {$(pwd)}
cd {$outdir}
array set options {$options}
diff --git a/etc/platforms/platforms.jmk b/etc/platforms/platforms.jmk
index f4bac15..9f1bd90 100644
--- a/etc/platforms/platforms.jmk
+++ b/etc/platforms/platforms.jmk
@@ -1,7 +1,8 @@
# -*- tcl -*-
isa x86_32
-device pc-generic x86_32
+device generic x86_32
isa riscv32
device esp32c3 riscv32
+# device generic riscv32
diff --git a/etc/platforms/riscv32/riscv32.jmk b/etc/platforms/riscv32/riscv32.jmk
new file mode 100644
index 0000000..f8249b9
--- /dev/null
+++ b/etc/platforms/riscv32/riscv32.jmk
@@ -0,0 +1,9 @@
+# -*- tcl -*-
+
+set ::ld "clang --target=riscv32"
+set ::cc "clang --target=riscv32"
+set ::asm "clang --target=riscv32"
+
+cflags -mcmodel=medany -march=rv32ima -mabi=ilp32
+asmflags -nostdlib -c
+ldflags $::cflags
diff --git a/etc/platforms/x86_32/x86_32.jmk b/etc/platforms/x86_32/x86_32.jmk
index e7cfbbb..9f8f4b0 100644
--- a/etc/platforms/x86_32/x86_32.jmk
+++ b/etc/platforms/x86_32/x86_32.jmk
@@ -1,3 +1,4 @@
# -*- tcl -*-
-# nothing
\ No newline at end of file
+cflag -m32
+asmflag -felf32
diff --git a/include/kernel/serial.h b/include/kernel/serial.h
new file mode 100644
index 0000000..7e391db
--- /dev/null
+++ b/include/kernel/serial.h
@@ -0,0 +1,8 @@
+#pragma once
+
+/**
+ * Initialize the default serial device.
+ */
+void init_serial();
+void serial_put(char byte);
+void serial_write(char *string);
diff --git a/share/jmk/jmk.tcl b/share/jmk/jmk.tcl
index ae114dc..1a82ffb 100644
--- a/share/jmk/jmk.tcl
+++ b/share/jmk/jmk.tcl
@@ -220,7 +220,7 @@
rule .s.o {} {
log ASM $::first_src
- asm "\ $::first_src -o $::target"
+ asm "$::asmflags $::first_src -o $::target"
}
rule clean {} {
@@ -242,23 +242,22 @@
cflags -O2
}
- proc 32 {} {
- cflag -m32
- asmflag -felf32
- }
-
proc debug {} {
cflag -g
- asmflag -Fdwarf
}
proc warn {} {
cflags -Wall -Wno-unused-function -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-sign-compare
}
+ proc 32 {} {
+ cflag -m32
+ asmflag -felf32
+ }
+
proc nasm {} {
- global asm
- set asm nasm
+ set ::asm nasm
+ asmflag -Fdwarf
}
}
diff --git a/share/jmk/multiplat.jmk b/share/jmk/multiplat.jmk
index 0638d8d..3111653 100644
--- a/share/jmk/multiplat.jmk
+++ b/share/jmk/multiplat.jmk
@@ -26,7 +26,7 @@
}
option ISA x86_32
-option DEVICE pc-generic
+option DEVICE generic
proc source_if_exists {path} {
if {[file exists $path]} {
diff --git a/src/kernel/Jmk2 b/src/kernel/Jmk2
index 38e44b9..ffd134c 100644
--- a/src/kernel/Jmk2
+++ b/src/kernel/Jmk2
@@ -2,7 +2,7 @@
init kernel kernel.elf
-presets freestanding debug 32 warn nasm
+presets freestanding debug warn
cflags -I$root/include/kernel -I$root/include -I[pwd] -O0 -Wno-ignored-qualifiers -Wno-unused-params -Wno-sign-compare
diff --git a/src/kernel/riscv32/boot.s b/src/kernel/riscv32/boot.s
new file mode 100644
index 0000000..6578eba
--- /dev/null
+++ b/src/kernel/riscv32/boot.s
@@ -0,0 +1,21 @@
+ .equ STACK_SIZE, 8192
+
+ .global _start
+
+_start:
+ csrr t0, mhartid
+ slli t0, t0, 10 # mhartid << 10
+ la sp, stacks + STACK_SIZE # set up space for hart stacks
+ add sp, sp, t0 # sp += (mhartid << 10)
+
+ ## For now, only run on hart 0
+ csrr a0, mhartid # pass hart id to kmain
+ bnez a0, .end
+ j kmain
+
+.end:
+ wfi
+ j .end
+
+stacks:
+ .skip STACK_SIZE * 4 # Allocate stack space for each hart
diff --git a/src/kernel/riscv32/esp32c3.jmk b/src/kernel/riscv32/esp32c3.jmk
new file mode 100644
index 0000000..3125e01
--- /dev/null
+++ b/src/kernel/riscv32/esp32c3.jmk
@@ -0,0 +1,9 @@
+# -*- tcl -*-
+
+ldflags -T[pwd]/link-esp32c3.ld
+
+srcs serial-esp32c3.c
+
+rule kernel.bin kernel.elf {
+ shell {objcopy -O binary $^ $@}
+}
diff --git a/src/kernel/riscv32/generic.jmk b/src/kernel/riscv32/generic.jmk
new file mode 100644
index 0000000..f167787
--- /dev/null
+++ b/src/kernel/riscv32/generic.jmk
@@ -0,0 +1,3 @@
+ldflags -T[pwd]/link.ld
+
+srcs serial-generic.c
\ No newline at end of file
diff --git a/src/kernel/riscv32/link-esp32c3.ld b/src/kernel/riscv32/link-esp32c3.ld
new file mode 100644
index 0000000..34c639f
--- /dev/null
+++ b/src/kernel/riscv32/link-esp32c3.ld
@@ -0,0 +1,369 @@
+MEMORY
+{
+ irom (x): org = 0x42000000, len = 0x400000
+ drom (r): org = 0x3C000000, len = 0x400000
+ ram (rw): org = 0x3FC80000, len = 0x50000
+ rtc_ram (rx): org = 0x50000000, len = 0x2000
+}
+
+ENTRY(_start)
+
+SECTIONS
+{
+ .header : AT(0)
+ {
+ _irom_start = .;
+ LONG(0xaedb041d)
+ LONG(0xaedb041d)
+ } > irom
+
+ .text.entry ORIGIN(irom) + 8 :
+ {
+ KEEP(*(.text.entry))
+ } > irom
+
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.gnu.warning)
+ }
+ . = ALIGN(4);
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ _irom_size = . - _irom_start;
+
+ _drom_start = ORIGIN(drom) + _irom_size;
+ .rodata _drom_start : AT(_irom_size)
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ } > drom
+
+ .rodata1 :
+ {
+ *(.rodata1)
+ }
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } > drom
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > drom
+
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+
+ _drom_size = . - _drom_start;
+
+ .data ORIGIN(ram) : AT(_irom_size + _drom_size)
+ {
+ _data_start = .;
+ __DATA_BEGIN__ = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
+ SORT(CONSTRUCTORS)
+ } > ram
+ .data1 :
+ {
+ *(.data1)
+ }
+ .sdata :
+ {
+ __SDATA_BEGIN__ = .;
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+ . = ALIGN(4);
+ _edata = .; PROVIDE (edata = .);
+ _data_lma = ORIGIN(drom) + LOADADDR(.data);
+ _data_size = _edata - _data_start;
+
+ __bss_start = .;
+ .sbss :
+ {
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4);
+ __BSS_END__ = .;
+ __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
+ MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
+ _end = .; PROVIDE (end = .);
+
+ /* Stack */
+ .stack :
+ {
+ __stack_bottom = .;
+ __stack_top = ORIGIN(ram) + LENGTH(ram);
+ __stack_size_min = 0x4000;
+ ASSERT(__stack_bottom + __stack_size_min < __stack_top, "Error: no space for stack");
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* DWARF Extension. */
+ .debug_macro 0 : { *(.debug_macro) }
+ .debug_addr 0 : { *(.debug_addr) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
+
+/* ESP32C3 ROM functions from ./interface-esp32c3.yml */
+
+/* Functions */
+__absvdi2 = 0x40000764;
+__absvsi2 = 0x40000768;
+__adddf3 = 0x4000076c;
+__addsf3 = 0x40000770;
+__addvdi3 = 0x40000774;
+__addvsi3 = 0x40000778;
+__ashldi3 = 0x4000077c;
+__ashrdi3 = 0x40000780;
+__bswapdi2 = 0x40000784;
+__bswapsi2 = 0x40000788;
+__clear_cache = 0x4000078c;
+__clrsbdi2 = 0x40000790;
+__clrsbsi2 = 0x40000794;
+__clzdi2 = 0x40000798;
+__clzsi2 = 0x4000079c;
+__cmpdi2 = 0x400007a0;
+__ctzdi2 = 0x400007a4;
+__ctzsi2 = 0x400007a8;
+__divdc3 = 0x400007ac;
+__divdf3 = 0x400007b0;
+__divdi3 = 0x400007b4;
+__divsc3 = 0x400007b8;
+__divsf3 = 0x400007bc;
+__divsi3 = 0x400007c0;
+__eqdf2 = 0x400007c4;
+__eqsf2 = 0x400007c8;
+__extendsfdf2 = 0x400007cc;
+__ffsdi2 = 0x400007d0;
+__ffssi2 = 0x400007d4;
+__fixdfdi = 0x400007d8;
+__fixdfsi = 0x400007dc;
+__fixsfdi = 0x400007e0;
+__fixsfsi = 0x400007e4;
+__fixunsdfsi = 0x400007e8;
+__fixunssfdi = 0x400007ec;
+__fixunssfsi = 0x400007f0;
+__floatdidf = 0x400007f4;
+__floatdisf = 0x400007f8;
+__floatsidf = 0x400007fc;
+__floatsisf = 0x40000800;
+__floatundidf = 0x40000804;
+__floatundisf = 0x40000808;
+__floatunsidf = 0x4000080c;
+__floatunsisf = 0x40000810;
+__gcc_bcmp = 0x40000814;
+__gedf2 = 0x40000818;
+__gesf2 = 0x4000081c;
+__gtdf2 = 0x40000820;
+__gtsf2 = 0x40000824;
+__ledf2 = 0x40000828;
+__lesf2 = 0x4000082c;
+__lshrdi3 = 0x40000830;
+__ltdf2 = 0x40000834;
+__ltsf2 = 0x40000838;
+__moddi3 = 0x4000083c;
+__modsi3 = 0x40000840;
+__muldc3 = 0x40000844;
+__muldf3 = 0x40000848;
+__muldi3 = 0x4000084c;
+__mulsc3 = 0x40000850;
+__mulsf3 = 0x40000854;
+__mulsi3 = 0x40000858;
+__mulvdi3 = 0x4000085c;
+__mulvsi3 = 0x40000860;
+__nedf2 = 0x40000864;
+__negdf2 = 0x40000868;
+__negdi2 = 0x4000086c;
+__negsf2 = 0x40000870;
+__negvdi2 = 0x40000874;
+__negvsi2 = 0x40000878;
+__nesf2 = 0x4000087c;
+__paritysi2 = 0x40000880;
+__popcountdi2 = 0x40000884;
+__popcountsi2 = 0x40000888;
+__powidf2 = 0x4000088c;
+__powisf2 = 0x40000890;
+__subdf3 = 0x40000894;
+__subsf3 = 0x40000898;
+__subvdi3 = 0x4000089c;
+__subvsi3 = 0x400008a0;
+__truncdfsf2 = 0x400008a4;
+__ucmpdi2 = 0x400008a8;
+__udivdi3 = 0x400008ac;
+__udivmoddi4 = 0x400008b0;
+__udivsi3 = 0x400008b4;
+__udiv_w_sdiv = 0x400008b8;
+__umoddi3 = 0x400008bc;
+__umodsi3 = 0x400008c0;
+__unorddf2 = 0x400008c4;
+__unordsf2 = 0x400008c8;
+
+
+/***************************************
+Group newlib
+***************************************/
+
+/* Functions */
+memset = 0x40000354;
+memcpy = 0x40000358;
+memmove = 0x4000035c;
+memcmp = 0x40000360;
+strcpy = 0x40000364;
+strncpy = 0x40000368;
+strcmp = 0x4000036c;
+strncmp = 0x40000370;
+strlen = 0x40000374;
+strstr = 0x40000378;
+bzero = 0x4000037c;
+isalnum = 0x40000388;
+isalpha = 0x4000038c;
+isascii = 0x40000390;
+isblank = 0x40000394;
+iscntrl = 0x40000398;
+isdigit = 0x4000039c;
+islower = 0x400003a0;
+isgraph = 0x400003a4;
+isprint = 0x400003a8;
+ispunct = 0x400003ac;
+isspace = 0x400003b0;
+isupper = 0x400003b4;
+toupper = 0x400003b8;
+tolower = 0x400003bc;
+toascii = 0x400003c0;
+memccpy = 0x400003c4;
+memchr = 0x400003c8;
+memrchr = 0x400003cc;
+strcasecmp = 0x400003d0;
+strcasestr = 0x400003d4;
+strcat = 0x400003d8;
+strdup = 0x400003dc;
+strchr = 0x400003e0;
+strcspn = 0x400003e4;
+strcoll = 0x400003e8;
+strlcat = 0x400003ec;
+strlcpy = 0x400003f0;
+strlwr = 0x400003f4;
+strncasecmp = 0x400003f8;
+strncat = 0x400003fc;
+strndup = 0x40000400;
+strnlen = 0x40000404;
+strrchr = 0x40000408;
+strsep = 0x4000040c;
+strspn = 0x40000410;
+strtok_r = 0x40000414;
+strupr = 0x40000418;
+longjmp = 0x4000041c;
+setjmp = 0x40000420;
+abs = 0x40000424;
+div = 0x40000428;
+labs = 0x4000042c;
+ldiv = 0x40000430;
+qsort = 0x40000434;
+rand_r = 0x40000438;
+rand = 0x4000043c;
+srand = 0x40000440;
+utoa = 0x40000444;
+itoa = 0x40000448;
+atoi = 0x4000044c;
+atol = 0x40000450;
+strtol = 0x40000454;
+strtoul = 0x40000458;
+
+uart_tx_one_char = 0x40000068;
+uart_rx_one_char = 0x40000070;
+uart_rx_one_char_block = 0x40000074;
+uart_tx_flush = 0x40000080;
+
+/***************************************
+Group gpio
+***************************************/
+
+/* Functions */
+gpio_input_get = 0x4000059c;
+gpio_matrix_in = 0x400005a0;
+gpio_matrix_out = 0x400005a4;
+gpio_output_disable = 0x400005a8;
+gpio_output_enable = 0x400005ac;
+gpio_output_set = 0x400005b0;
+gpio_pad_hold = 0x400005b4;
+gpio_pad_input_disable = 0x400005b8;
+gpio_pad_input_enable = 0x400005bc;
+gpio_pad_pulldown = 0x400005c0;
+gpio_pad_pullup = 0x400005c4;
+gpio_pad_select_gpio = 0x400005c8;
+gpio_pad_set_drv = 0x400005cc;
+gpio_pad_unhold = 0x400005d0;
+gpio_pin_wakeup_disable = 0x400005d4;
+gpio_pin_wakeup_enable = 0x400005d8;
+gpio_bypass_matrix_in = 0x400005dc;
diff --git a/src/kernel/riscv32/link-old.ld b/src/kernel/riscv32/link-old.ld
new file mode 100644
index 0000000..eea882d
--- /dev/null
+++ b/src/kernel/riscv32/link-old.ld
@@ -0,0 +1,170 @@
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+SECTIONS
+{
+ .header : AT(0)
+ {
+ _irom_start = .;
+ LONG(0xaedb041d)
+ LONG(0xaedb041d)
+ } > irom
+
+ .text.entry ORIGIN(irom) + 8 :
+ {
+ KEEP(*(.text.entry))
+ } > irom
+
+ .text :
+ {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.gnu.warning)
+ }
+ . = ALIGN(4);
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ _irom_size = . - _irom_start;
+
+ _drom_start = ORIGIN(drom) + _irom_size;
+ .rodata _drom_start : AT(_irom_size)
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ } > drom
+
+ .rodata1 :
+ {
+ *(.rodata1)
+ }
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } > drom
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > drom
+
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+
+ _drom_size = . - _drom_start;
+
+ .data ORIGIN(ram) : AT(_irom_size + _drom_size)
+ {
+ _data_start = .;
+ __DATA_BEGIN__ = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
+ SORT(CONSTRUCTORS)
+ } > ram
+ .data1 :
+ {
+ *(.data1)
+ }
+ .sdata :
+ {
+ __SDATA_BEGIN__ = .;
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+ . = ALIGN(4);
+ _edata = .; PROVIDE (edata = .);
+ _data_lma = ORIGIN(drom) + LOADADDR(.data);
+ _data_size = _edata - _data_start;
+
+ __bss_start = .;
+ .sbss :
+ {
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ }
+ . = ALIGN(4);
+ __BSS_END__ = .;
+ __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
+ MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));
+ _end = .; PROVIDE (end = .);
+
+ /* Stack */
+ .stack :
+ {
+ __stack_bottom = .;
+ __stack_top = ORIGIN(ram) + LENGTH(ram);
+ __stack_size_min = 0x4000;
+ ASSERT(__stack_bottom + __stack_size_min < __stack_top, "Error: no space for stack");
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* DWARF Extension. */
+ .debug_macro 0 : { *(.debug_macro) }
+ .debug_addr 0 : { *(.debug_addr) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
diff --git a/src/kernel/riscv32/link.ld b/src/kernel/riscv32/link.ld
new file mode 100644
index 0000000..abbd617
--- /dev/null
+++ b/src/kernel/riscv32/link.ld
@@ -0,0 +1,46 @@
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( _start )
+
+MEMORY
+{
+ ram (rw) : ORIGIN = 0x80000000, LENGTH = 128M
+}
+
+PHDRS
+{
+ text PT_LOAD;
+ data PT_LOAD;
+ bss PT_LOAD;
+}
+
+SECTIONS
+{
+ .text : {
+ PROVIDE(_text_start = .);
+ *(.text.init) *(.text .text.*)
+ PROVIDE(_text_end = .);
+ } >ram AT>ram :text
+
+ .rodata : {
+ PROVIDE(_rodata_start = .);
+ *(.rodata .rodata.*)
+ PROVIDE(_rodata_end = .);
+ } >ram AT>ram :text
+
+ .data : {
+ . = ALIGN(4096);
+ PROVIDE(_data_start = .);
+ *(.sdata .sdata.*) *(.data .data.*)
+ PROVIDE(_data_end = .);
+ } >ram AT>ram :data
+
+ .bss :{
+ PROVIDE(_bss_start = .);
+ *(.sbss .sbss.*) *(.bss .bss.*)
+ PROVIDE(_bss_end = .);
+ } >ram AT>ram :bss
+
+ PROVIDE(_memory_start = ORIGIN(ram));
+ PROVIDE(_memory_end = ORIGIN(ram) + LENGTH(ram));
+}
diff --git a/src/kernel/riscv32/main.c b/src/kernel/riscv32/main.c
new file mode 100644
index 0000000..9603292
--- /dev/null
+++ b/src/kernel/riscv32/main.c
@@ -0,0 +1,13 @@
+#include "kint.h"
+#include "serial.h"
+
+void kmain(uint mhartid)
+{
+ init_serial();
+
+ serial_write("Hello from Bluejay!\r\n");
+
+ while (true)
+ {
+ }
+}
diff --git a/src/kernel/riscv32/riscv32.jmk b/src/kernel/riscv32/riscv32.jmk
new file mode 100644
index 0000000..d90b47a
--- /dev/null
+++ b/src/kernel/riscv32/riscv32.jmk
@@ -0,0 +1,10 @@
+# -*- tcl -*-
+
+srcs boot.s \
+ main.c
+
+rule qemu "" {
+ shell "qemu-system-riscv32 -M ? | grep virt >/dev/null || exit"
+ shell "echo C-a X to exit qemu"
+ shell "qemu-system-riscv32 -nographic -smp 4 -machine virt -bios none -kernel kernel.elf"
+}
diff --git a/src/kernel/riscv32/serial-esp32c3.c b/src/kernel/riscv32/serial-esp32c3.c
new file mode 100644
index 0000000..32b8178
--- /dev/null
+++ b/src/kernel/riscv32/serial-esp32c3.c
@@ -0,0 +1,32 @@
+#include "serial.h"
+#include "kint.h"
+
+extern int uart_tx_one_char(char byte);
+
+/**
+ * @param c Pointer to input
+ * @returns OK or not
+ */
+extern bool uart_rx_one_char(char *c);
+
+/**
+ * @param uart_no UART number
+ */
+extern void uart_tx_flush(uchar uart_no);
+
+void init_serial()
+{
+}
+
+void serial_put(char byte)
+{
+ uart_tx_one_char(byte);
+}
+
+void serial_write(char *string)
+{
+ while (*string)
+ {
+ serial_put(*string++);
+ }
+}
diff --git a/src/kernel/riscv32/serial-generic.c b/src/kernel/riscv32/serial-generic.c
new file mode 100644
index 0000000..ea231d9
--- /dev/null
+++ b/src/kernel/riscv32/serial-generic.c
@@ -0,0 +1,35 @@
+#include "kint.h"
+#include "serial.h"
+
+/* Base address for QEMU */
+/* TODO: Abstract for ESP32C3 */
+#define UART_BASE (void *)0x10000000
+#define UART_LSR_EMPTY_MASK 0x40
+
+/* UART transmitter holding register */
+uchar *uart_thr = UART_BASE;
+
+/* UART line status register */
+uchar *uart_lsr = UART_BASE + 5;
+
+void init_serial()
+{
+}
+
+void serial_put(char byte)
+{
+ while (*uart_lsr ^ UART_LSR_EMPTY_MASK)
+ {
+ /* block until UART clear */
+ }
+
+ *uart_thr = byte;
+}
+
+void serial_write(char *string)
+{
+ while (*string)
+ {
+ serial_put(*string++);
+ }
+}
diff --git a/src/lisp/Jmk b/src/lisp/Jmk
deleted file mode 100644
index 022fcc0..0000000
--- a/src/lisp/Jmk
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- mode:makefile -*-
-
-init(lisp, lisp)
-
-option(PLAT, "`platform to build for: either linux or bluejay'", linux)
-
-# preset(optimize)
-preset(32)
-preset(debug)
-preset(warn)
-preset(nasm)
-
-archetype(c)
-archetype(asm)
-
-NO_READLINE ?= 0
-
-CFLAGS += -Ivendor/luajit/dynasm -Werror # -fsanitize=address
-ASMFLAGS += -felf -Fdwarf
-
-ifeq ($(NO_READLINE),1)
-CFLAGS += -DNO_READLINE
-else
-LDFLAGS += -lreadline
-CFLAGS += -lreadline
-endif
-
-OBJECTS = main.o \
- lisp.o \
- compiler.o \
- lib/std.o \
- plat/linux.o \
- istream.o \
- gc.o \
- call_list.o \
- error.o
-
-LUA = vendor/luajit/src/host/minilua
-
-$(LUA): vendor/luajit/src/host/minilua.c
- status_log(CC, $<)
- @$(CC) $< -o $@ -lm
-
-compiler.c: compiler.dasc | $(LUA)
- status_log(DYNASM, $<)
- @$(LUA) vendor/luajit/dynasm/dynasm.lua -o $@ $<
-
-type(executable)
-
-F ?= test.lisp
-lisp_libpath = $(ROOT)/lib/lisp
-
-run: lisp
- status_log(LISP, $(F))
- @LISP_LIBRARY_PATH="$(lisp_libpath)" ./lisp $(F)
-
-repl: lisp
- status_log(LISP, repl)
- @LISP_LIBRARY_PATH="$(lisp_libpath)" ./lisp $(ROOT)/lib/lisp/repl/repl.lisp
-
-leak-check: lisp
- status_log(VALGRIND, lisp $(F))
- @LISP_LIBRARY_PATH="$(lisp_libpath)" valgrind --leak-check=full ./lisp $(F)
-
-format:
- status_log(FORMAT, *)
- @clang-format -i *.c *.h *.dasc plat/* lib/*
-
-finish
diff --git a/src/lisp/Jmk2 b/src/lisp/Jmk2
index 1f4e6b1..5446f50 100644
--- a/src/lisp/Jmk2
+++ b/src/lisp/Jmk2
@@ -2,6 +2,10 @@
init lisp
+presets 32 debug warn nasm
+cflags -Ivendor/luajit/dynasm -O0
+asmflags -felf32
+
# Make this `readline', `edit', or `none'
option READLINE readline
@@ -13,10 +17,6 @@
cflags -L/usr/lib/i386-linux-gnu -l$options(READLINE)
}
-presets 32 debug warn nasm
-cflags -Ivendor/luajit/dynasm -O0
-asmflags -felf32
-
set lua [pwd]/vendor/luajit/src/host/minilua
rule $lua ${lua}.c {