From 72a403ce29627ad6fb603c366b239ba8c9e5131e Mon Sep 17 00:00:00 2001
From: Christian Cunningham <cc@localhost>
Date: Wed, 30 Mar 2022 16:22:09 -0700
Subject: Allow C++ user code

---
 Common.mk         | 15 ++++++++++++++-
 include/usr/cxx.h |  6 ++++++
 usr/cxx.cpp       | 24 ++++++++++++++++++++++++
 usr/main.c        |  4 +++-
 4 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 include/usr/cxx.h
 create mode 100644 usr/cxx.cpp

diff --git a/Common.mk b/Common.mk
index b8af1ca..5ca4a58 100644
--- a/Common.mk
+++ b/Common.mk
@@ -2,6 +2,9 @@
 C_SOURCEK = $(wildcard kernel/*.c kernel/**/*.c)
 C_OBJECTk = ${C_SOURCEK:.c=.co}
 C_OBJECTK = ${subst kernel/,obj/kernel/,${C_OBJECTk}}
+CXX_SOURCEK = $(wildcard kernel/*.cpp kernel/**/*.cpp)
+CXX_OBJECTk = ${CXX_SOURCEK:.cpp=.cppo}
+CXX_OBJECTK = ${subst kernel/,obj/kernel/,${CXX_OBJECTk}}
 A_SOURCEK = $(wildcard kernel/*.S kernel/**/*.S)
 A_OBJECTk = ${A_SOURCEK:.S=.ao}
 A_OBJECTK = ${subst kernel/,obj/kernel/,${A_OBJECTk}}
@@ -9,11 +12,15 @@ A_OBJECTK = ${subst kernel/,obj/kernel/,${A_OBJECTk}}
 C_SOURCEU = $(wildcard usr/*.c usr/**/*.c)
 C_OBJECTu = ${C_SOURCEU:.c=.co}
 C_OBJECTU = ${subst usr/,obj/usr/,${C_OBJECTu}}
+CXX_SOURCEU = $(wildcard usr/*.cpp usr/**/*.cpp)
+CXX_OBJECTu = ${CXX_SOURCEU:.cpp=.cppo}
+CXX_OBJECTU = ${subst usr/,obj/usr/,${CXX_OBJECTu}}
 A_SOURCEU = $(wildcard usr/*.S usr/**/*.S)
 A_OBJECTu = ${A_SOURCEU:.S=.ao}
 A_OBJECTU = ${subst usr/,obj/usr/,${A_OBJECTu}}
 # Combined Objects
 C_OBJECTD = $(C_OBJECTK) $(C_OBJECTU)
+CXX_OBJECTD = $(CXX_OBJECTK) $(CXX_OBJECTU)
 A_OBJECTD = $(A_OBJECTK) $(A_OBJECTU)
 
 ATTACH_USB ?= 0
@@ -26,12 +33,14 @@ DISK ?= /dev/sdc1
 
 CROSS = arm-none-eabi
 CC = ${CROSS}-gcc
+CCPP = ${CROSS}-g++
 AS = ${CROSS}-as
 OBJCOPY = ${CROSS}-objcopy
 OBJDUMP = ${CROSS}-objdump
 QEMU = qemu-system-arm
 GDB = gdb-multiarch
 CFLAGS = -mcpu=cortex-a7 -fpic -ffreestanding -std=gnu99 -O3 -Wall -Wextra -nostdlib -Iinclude -g
+CXXFLAGS = -mcpu=cortex-a7 -fpic -ffreestanding -O3 -Wall -Wextra -nostdlib -Iinclude -g
 CFLAGS += -DVERSION="\"0.9z\""
 AFLAGS = -mcpu=cortex-a7 -Iinclude -g
 QFLAGS = -M raspi2b -cpu cortex-a7 -m 1G
@@ -92,7 +101,7 @@ build/kernel.list: build/kernel.elf
 
 dump: build/kernel.list
 
-build/kernel.elf: ${A_OBJECTD} ${C_OBJECTD}
+build/kernel.elf: ${A_OBJECTD} ${CXX_OBJECTD} ${C_OBJECTD}
 	@tput setaf 6 2> /dev/null || true; echo Linking Kernel; tput sgr0 2> /dev/null || true
 	@mkdir -p $(@D)
 	@echo ${C_SOURCEK}
@@ -110,6 +119,10 @@ obj/usr/%.co: usr/%.c
 	@mkdir -p $(@D)
 	${CC} ${CFLAGS} -c $< -o $@
 
+obj/usr/%.cppo: usr/%.cpp
+	@mkdir -p $(@D)
+	${CCPP} ${CXXFLAGS} -c $< -o $@
+
 obj/usr/%.ao: usr/%.S
 	@mkdir -p $(@D)
 	${AS} ${AFLAGS} -c $< -o $@
diff --git a/include/usr/cxx.h b/include/usr/cxx.h
new file mode 100644
index 0000000..ddce889
--- /dev/null
+++ b/include/usr/cxx.h
@@ -0,0 +1,6 @@
+#ifndef USR_CXX_H
+#define USR_CXX_H
+
+void cpp_demo(unsigned long);
+
+#endif
diff --git a/usr/cxx.cpp b/usr/cxx.cpp
new file mode 100644
index 0000000..0c41cca
--- /dev/null
+++ b/usr/cxx.cpp
@@ -0,0 +1,24 @@
+extern "C" {
+#include <drivers/uart.h>
+};
+
+class TestClass {
+	public:
+		unsigned long value;
+		TestClass(unsigned long v) {
+			value = v;
+		}
+		void increment() {
+			value++;
+		}
+		void increment(unsigned long v) {
+			value += v;
+		}
+};
+
+extern "C" void cpp_demo(unsigned long v)
+{
+	TestClass tc = TestClass(v);
+	tc.increment();
+	uart_hexn(tc.value);
+}
diff --git a/usr/main.c b/usr/main.c
index a4c6048..0308d4b 100644
--- a/usr/main.c
+++ b/usr/main.c
@@ -4,10 +4,11 @@
 #include <graphics/lfb.h>
 #include <symbols.h>
 #include <sys/schedule.h>
+#include <usr/cxx.h>
+#include <usr/math.h>
 #include <usr/string.h>
 #include <usr/timed.h>
 #include <usr/uart.h>
-#include <usr/math.h>
 
 static struct SysTimerInfo stime_0 = {
 	.tick_rate = 5000000,
@@ -99,4 +100,5 @@ void main(void)
 	//add_thread(consumer, 0, 3);
 	//add_thread(test_super, 0, 4);
 	//subscribe_irq(SYS_TIMER_3_IRQ, gptest, &stime_3);
+	cpp_demo(53);
 }
-- 
cgit v1.2.1