diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/amd64/Makefile | 11 | ||||
| -rw-r--r-- | sys/arch/amd64/boot/apboot.asm | 38 | ||||
| -rw-r--r-- | sys/arch/amd64/conf/link.ld | 4 | ||||
| -rw-r--r-- | sys/arch/amd64/cpu/mp.c | 134 | ||||
| -rw-r--r-- | sys/inc/mu/cpu.h | 5 | ||||
| -rw-r--r-- | sys/kern/kern_init.c | 1 |
6 files changed, 190 insertions, 3 deletions
diff --git a/sys/arch/amd64/Makefile b/sys/arch/amd64/Makefile index 3430e48..ba821ae 100644 --- a/sys/arch/amd64/Makefile +++ b/sys/arch/amd64/Makefile @@ -4,16 +4,17 @@ override PROMPT := printf "%s\t\t%s\n" CC = LD = SYS_CFLAGS = -ASMFILES = $(shell find . -name "*.S") +ASMFILES = $(shell find . -name "*.S" | grep -v "boot/") CFILES = $(shell find . -name "*.c") ASMOBJS = $(ASMFILES:.S=.S.o) COBJ = $(CFILES:.c=.o) DFILES = $(CFILES:.c=.d) -MISC_OFILES = $(shell find ../../ -name "*.o") +MISC_OFILES = $(shell find ../../ -name "*.o" | grep -v "boot/") .PHONY: all -all: $(ASMOBJS) $(COBJ) +all: boot $(ASMOBJS) $(COBJ) $(LD) -Tconf/link.ld $(MISC_OFILES) -o ../../rv7 + objcopy --update-section .trampoline=boot/apboot.bin ../../rv7 %.S.o: %.S $(PROMPT) " [AS] " $< @@ -24,6 +25,10 @@ all: $(ASMOBJS) $(COBJ) $(PROMPT) " [CC] " $< $(CC) -c -MMD -I../../target/inc/ -I../../inc/ $(SYS_CFLAGS) $< -o $@ +.PHONY: boot +boot: + nasm -fbin boot/apboot.asm -o boot/apboot.bin + .PHONY: clean clean: rm $(MISC_OFILES) diff --git a/sys/arch/amd64/boot/apboot.asm b/sys/arch/amd64/boot/apboot.asm new file mode 100644 index 0000000..b9c3ad7 --- /dev/null +++ b/sys/arch/amd64/boot/apboot.asm @@ -0,0 +1,38 @@ +;; +;; Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. +;; All rights reserved. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions are met: +;; +;; 1. Redistributions of source code must retain the above copyright notice, +;; this list of conditions and the following disclaimer. +;; 2. Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in the +;; documentation and/or other materials provided with the distribution. +;; 3. Neither the name of Hyra nor the names of its +;; contributors may be used to endorse or promote products derived from +;; this software without specific prior written permission. +;; +;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPKERNE +;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;; SUBSTITUTE GOODS OR SERVICES; LKERNS OF USE, DATA, OR PROFITS; OR BUSINESS +;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;; PKERNSIBILITY OF SUCH DAMAGE. +;; + +[bits 16] +[org 0x1000] + +_start: + cli + hlt + jmp _start + +times 4096 - ($ - $$) db 0 diff --git a/sys/arch/amd64/conf/link.ld b/sys/arch/amd64/conf/link.ld index 92222b0..9ae1a01 100644 --- a/sys/arch/amd64/conf/link.ld +++ b/sys/arch/amd64/conf/link.ld @@ -23,6 +23,10 @@ SECTIONS *(.rodata .rodata.*) } :rodata + .trampoline : ALIGN(8) { + *(.trampoline.*) + } + . += CONSTANT(MAXPAGESIZE); .data : { diff --git a/sys/arch/amd64/cpu/mp.c b/sys/arch/amd64/cpu/mp.c new file mode 100644 index 0000000..09c824e --- /dev/null +++ b/sys/arch/amd64/cpu/mp.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/cdefs.h> +#include <acpi/acpi.h> +#include <os/trace.h> +#include <kern/panic.h> +#include <dev/clkdev/hpet.h> +#include <lib/string.h> +#include <md/lapic.h> +#include <mu/cpu.h> +#include <vm/vm.h> + +#define dtrace(fmt, ...) trace("mp: " fmt, ##__VA_ARGS__) + +/* + * The startup code is copied to the processor bring up area + * to which it is executed in real mode. This area must fit + * within a page and be no larger and no smaller. + */ +#define AP_BUA_LEN 0x1000 /* Bring up area length in bytes */ +#define AP_BUA_PADDR 0x1000 /* Bring up area [physical] */ +#define AP_BUA_VADDR PHYS_TO_VIRT(AP_BUA_PADDR) /* Bring up area [virtual] */ + +__section(".trampoline") static char ap_code[4096]; + +static int +cpu_lapic_cb(struct apic_header *h, size_t arg) +{ + struct local_apic *lapic; + struct cpu_info *self; + struct mcb *mcb; + struct lapic_ipi ipi; + int error; + + self = cpu_self(); + if (self == NULL) { + panic("mp: could not get self\n"); + } + + mcb = &self->mcb; + + /* Skip ourselves */ + lapic = (struct local_apic *)h; + if (lapic->apic_id == arg) { + return -1; + } + + /* Prepare the IPI packet */ + ipi.dest_id = lapic->apic_id; + ipi.vector = 0; + ipi.delmod = IPI_DELMOD_INIT; + ipi.shorthand = IPI_SHAND_NONE; + ipi.logical_dest = 0; + error = lapic_send_ipi(mcb, &ipi); + if (error < 0) { + panic("mp: failed to send INIT IPI\n"); + } + + /* Give it 20ms then prep a STARTUP */ + hpet_msleep(20); + ipi.delmod = IPI_DELMOD_STARTUP; + ipi.vector = (AP_BUA_PADDR >> 12); + + /* The MPSpec says to send two */ + for (uint8_t i = 0; i < 2; ++i) { + error = lapic_send_ipi(mcb, &ipi); + if (error != 0) { + panic("mp: failed to send STARTUP IPI\n"); + } + hpet_msleep(2); + } + + dtrace("bootstrapping lapic %d\n", lapic->apic_id); + return -1; /* Keep going */ +} + +void +cpu_start_aps(struct cpu_info *ci) +{ + struct cpu_info *self; + struct mcb *mcb; + size_t bua_len; + uint8_t *bua; + + if (ci == NULL) { + return; + } + + self = cpu_self(); + if (self == NULL) { + panic("mp: could not get current processor\n"); + } + + /* Copy the bring up code to the BUA */ + bua = AP_BUA_VADDR; + memcpy(bua, ap_code, AP_BUA_LEN); + + /* Start up the APs */ + mcb = &self->mcb; + dtrace("bringing up application processors...\n"); + acpi_read_madt( + APIC_TYPE_LOCAL_APIC, + cpu_lapic_cb, + lapic_read_id(mcb) + ); +} diff --git a/sys/inc/mu/cpu.h b/sys/inc/mu/cpu.h index 8965ec3..141843d 100644 --- a/sys/inc/mu/cpu.h +++ b/sys/inc/mu/cpu.h @@ -55,4 +55,9 @@ struct cpu_info *cpu_self(void); */ void cpu_conf(struct cpu_info *ci); +/* + * Bring up application processors + */ +void cpu_start_aps(struct cpu_info *ci); + #endif /* !_MU_CPU_H_ */ diff --git a/sys/kern/kern_init.c b/sys/kern/kern_init.c index dbe3af0..8c58ff4 100644 --- a/sys/kern/kern_init.c +++ b/sys/kern/kern_init.c @@ -48,4 +48,5 @@ kmain(void) vm_init(); acpi_init(); cpu_conf(&g_bsp); + cpu_start_aps(&g_bsp); } |
