aboutsummaryrefslogtreecommitdiff
path: root/mubios
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-08 07:56:59 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-08 07:56:59 +0800
commit33321fd8115007f3f1bffa3a9969c2444d5a578b (patch)
tree32a472453d226d9c49f99815ec413b28be1ff492 /mubios
parente939a810a401b389a398aa10499e7be142bf45ca (diff)
downloadrcc-project-33321fd8115007f3f1bffa3a9969c2444d5a578b.tar.gz
rcc-project-33321fd8115007f3f1bffa3a9969c2444d5a578b.tar.xz
[mubios] Implement INT 15h E820h
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'mubios')
-rw-r--r--mubios/arch/interrupt.S1
-rw-r--r--mubios/core/bda.c2
-rw-r--r--mubios/core/interrupt.c4
-rw-r--r--mubios/include/bios.h1
-rw-r--r--mubios/services/int15.c84
5 files changed, 92 insertions, 0 deletions
diff --git a/mubios/arch/interrupt.S b/mubios/arch/interrupt.S
index b3a461b..805cc50 100644
--- a/mubios/arch/interrupt.S
+++ b/mubios/arch/interrupt.S
@@ -87,3 +87,4 @@ int1a_return:
BIOS_SERVICE_ENTRY int10_entry, 0x10
BIOS_SERVICE_ENTRY int13_entry, 0x13
+ BIOS_SERVICE_ENTRY int15_entry, 0x15
diff --git a/mubios/core/bda.c b/mubios/core/bda.c
index d7be60c..8417605 100644
--- a/mubios/core/bda.c
+++ b/mubios/core/bda.c
@@ -59,6 +59,7 @@ extern void irq1_entry (void);
extern void int1a_entry (void);
extern void int10_entry (void);
extern void int13_entry (void);
+extern void int15_entry (void);
static void
install_ivt_entry (u8 vector, void (*handler) (void))
@@ -83,4 +84,5 @@ ivt_init (void)
install_ivt_entry (0x1Au, int1a_entry);
install_ivt_entry (0x10u, int10_entry);
install_ivt_entry (0x13u, int13_entry);
+ install_ivt_entry (0x15u, int15_entry);
}
diff --git a/mubios/core/interrupt.c b/mubios/core/interrupt.c
index a9b3ce6..9c71492 100644
--- a/mubios/core/interrupt.c
+++ b/mubios/core/interrupt.c
@@ -35,6 +35,10 @@ bios_service_dispatch (u8 vector, struct bios_regs *regs)
int13_service (regs);
break;
+ case 0x15u:
+ int15_service (regs);
+ break;
+
default:
regs->eax = 0x0100u;
regs->flags |= 0x0001u;
diff --git a/mubios/include/bios.h b/mubios/include/bios.h
index 9c14a42..1094bed 100644
--- a/mubios/include/bios.h
+++ b/mubios/include/bios.h
@@ -57,5 +57,6 @@ struct bios_regs;
void bios_service_dispatch (u8 vector, struct bios_regs *regs);
void int10_service (struct bios_regs *regs);
void int13_service (struct bios_regs *regs);
+void int15_service (struct bios_regs *regs);
#endif // MUBIOS_BIOS_H
diff --git a/mubios/services/int15.c b/mubios/services/int15.c
new file mode 100644
index 0000000..eb66f5c
--- /dev/null
+++ b/mubios/services/int15.c
@@ -0,0 +1,84 @@
+/*
+ RCC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+ */
+
+#include "bios.h"
+#include "regs.h"
+
+#define BIOS_CF 0x0001u
+#define E820_SIGNATURE 0x534D4150u
+#define E820_FUNCTION 0x0000E820u
+#define E820_ENTRY_SIZE 20u
+
+struct e820_entry
+{
+ u32 base_low;
+ u32 base_high;
+ u32 length_low;
+ u32 length_high;
+ u32 type;
+} __attribute__ ((packed));
+
+static const struct e820_entry e820_map[]
+ = { { 0x00000000u, 0x00000000u, 0x0009C000u, 0x00000000u, 1u },
+ { 0x0009C000u, 0x00000000u, 0x00004000u, 0x00000000u, 2u },
+ { 0x000A0000u, 0x00000000u, 0x00060000u, 0x00000000u, 2u },
+ { 0x00100000u, 0x00000000u, 0x07F00000u, 0x00000000u, 1u } };
+
+#define E820_ENTRY_COUNT ((u32)(sizeof (e820_map) / sizeof (e820_map[0])))
+
+static void
+int15_fail (struct bios_regs *regs)
+{
+ regs->eax = 0x8600u;
+ regs->flags |= BIOS_CF;
+}
+
+void
+int15_service (struct bios_regs *regs)
+{
+ struct e820_entry *output;
+ u32 index;
+ u32 address;
+
+ if (regs->eax != E820_FUNCTION || regs->edx != E820_SIGNATURE
+ || regs->ecx < E820_ENTRY_SIZE)
+ {
+ int15_fail (regs);
+ return;
+ }
+
+ index = regs->ebx;
+
+ if (index >= E820_ENTRY_COUNT)
+ {
+ int15_fail (regs);
+ return;
+ }
+
+ address = ((u32)regs->es << 4) + (u16)regs->edi;
+ output = (struct e820_entry *)address;
+
+ *output = e820_map[index];
+
+ regs->eax = E820_SIGNATURE;
+ regs->ecx = E820_ENTRY_SIZE;
+
+ index++;
+ regs->ebx = index < E820_ENTRY_COUNT ? index : 0u;
+ regs->flags &= (u16)~BIOS_CF;
+}