summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-10-04 00:47:53 +0200
committerRichard Braun <rbraun@sceen.net>2017-10-04 00:47:53 +0200
commit2f26df6d916daf1d4dbba9b2a91e7fe237329534 (patch)
tree97fece93a97149c778d4e297b8b0e014a41a827f
parent94b7a411a2aacc75ef823c15ffad52cbbabab738 (diff)
Hello, world!
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/machine/asm.h42
-rw-r--r--arch/arm/machine/boot.c33
-rw-r--r--arch/arm/machine/boot.h21
-rw-r--r--arch/arm/machine/boot_asm.S65
-rw-r--r--arch/arm/machine/cpu.h17
-rw-r--r--arch/arm/machine/pmap.h2
-rw-r--r--arch/arm/machine/tcb_asm.S21
-rw-r--r--arch/arm/x15.lds.S33
-rw-r--r--arch/x86/machine/asm.h8
10 files changed, 215 insertions, 29 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7c74a409..84214f0a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -1,6 +1,7 @@
KCONFIG_DEFCONFIG := qemu_virt_defconfig
XBUILD_CFLAGS += -mcpu=cortex-a15
+XBUILD_CFLAGS += -fdelete-null-pointer-checks
x15_SOURCES-y += \
arch/arm/machine/boot_asm.S \
@@ -8,4 +9,5 @@ x15_SOURCES-y += \
arch/arm/machine/cpu.c \
arch/arm/machine/pmap.c \
arch/arm/machine/strace.c \
+ arch/arm/machine/tcb_asm.S \
arch/arm/machine/tcb.c
diff --git a/arch/arm/machine/asm.h b/arch/arm/machine/asm.h
new file mode 100644
index 00000000..6474b225
--- /dev/null
+++ b/arch/arm/machine/asm.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012 Richard Braun.
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _X86_ASM_H
+#define _X86_ASM_H
+
+#ifndef __ASSEMBLER__
+#warning "asm.h included from a C file"
+#endif /* __ASSEMBLER__ */
+
+#include <machine/cpu.h>
+
+#define ASM_FUNC(x) \
+.align CPU_TEXT_SHIFT; \
+.global x; \
+.type x, STT_FUNC; \
+x
+
+#define ASM_DATA(x) \
+.align CPU_DATA_SHIFT; \
+.global x; \
+.type x, STT_OBJECT; \
+x
+
+#define ASM_END(x) \
+.size x, . - x
+
+#endif /* _X86_ASM_H */
diff --git a/arch/arm/machine/boot.c b/arch/arm/machine/boot.c
index 121ad92a..eb054f66 100644
--- a/arch/arm/machine/boot.c
+++ b/arch/arm/machine/boot.c
@@ -15,8 +15,41 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdalign.h>
+#include <stddef.h>
+#include <stdint.h>
+
#include <kern/init.h>
#include <machine/boot.h>
+#include <machine/cpu.h>
+#include <machine/pmap.h>
+#include <vm/vm_kmem.h>
+
+alignas(CPU_DATA_ALIGN) char boot_stack[BOOT_STACK_SIZE] __bootdata;
+
+static char boot_hello_msg[] __bootdata = "Hello, world!\r\n";
+
+static void __boot
+boot_hello_world(void)
+{
+ volatile unsigned long *uart_data_reg = (volatile unsigned long *)0x9000000;
+ const char *s = boot_hello_msg;
+
+ while (*s != '\0') {
+ *uart_data_reg = *s;
+ s++;
+ }
+}
+
+void boot_setup_paging(void);
+
+void __boot
+boot_setup_paging(void)
+{
+ boot_hello_world();
+
+ for (;;);
+}
void __init
boot_log_info(void)
diff --git a/arch/arm/machine/boot.h b/arch/arm/machine/boot.h
index 6459e80b..0181f7a0 100644
--- a/arch/arm/machine/boot.h
+++ b/arch/arm/machine/boot.h
@@ -19,16 +19,33 @@
#define _ARM_BOOT_H
#include <kern/macros.h>
+#include <machine/page.h>
#include <machine/pmap.h>
-#define BOOT_OFFSET DECL_CONST(0x0, UL)
+/*
+ * Size of the stack used when booting a processor.
+ */
+#define BOOT_STACK_SIZE PAGE_SIZE
+
+#define BOOT_LOAD_SECTION .boot.load
+#define BOOT_TEXT_SECTION .boot.text
+#define BOOT_DATA_SECTION .boot.data
-#define BOOT_VTOP(addr) ((addr) - PMAP_KERNEL_OFFSET)
+#define BOOT_RAM_START 0x40000000 /* XXX Specific to the Qemu virtual machine */
+#define BOOT_KERNEL_OFFSET (PMAP_START_KERNEL_ADDRESS - BOOT_RAM_START)
+
+#define BOOT_RTOL(addr) ((addr) - BOOT_RAM_START)
+#define BOOT_VTOL(addr) ((addr) - PMAP_START_KERNEL_ADDRESS)
+
+#define BOOT_VTOP(addr) ((addr) - BOOT_RAM_START)
#ifndef __ASSEMBLER__
#include <kern/init.h>
+#define __boot __section(QUOTE(BOOT_TEXT_SECTION))
+#define __bootdata __section(QUOTE(BOOT_DATA_SECTION)) __attribute__((used))
+
/*
* Log kernel version and other architecture-specific information.
*/
diff --git a/arch/arm/machine/boot_asm.S b/arch/arm/machine/boot_asm.S
index ccf3eb05..fedb63bb 100644
--- a/arch/arm/machine/boot_asm.S
+++ b/arch/arm/machine/boot_asm.S
@@ -15,11 +15,64 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-.section .boot.hdr, "awx"
+#include <machine/asm.h>
+#include <machine/boot.h>
+#include <machine/pmap.h>
-.long _start
+.section BOOT_LOAD_SECTION, "awx"
-.global _start
-_start:
- mov %r0, #0x12
- b .
+ASM_DATA(boot_exception_table):
+ .long _start /* Reset */
+ .long 0 /* Undefined instruction */
+ .long 0 /* Software interrupt */
+ .long 0 /* Prefetch abort */
+ .long 0 /* Data abort */
+ .long 0 /* IRQ */
+ .long 0 /* FIQ */
+ASM_END(boot_exception_table)
+
+ASM_FUNC(_start):
+ /*
+ * Assume the code runs from flash. For the sake of simplicity, make
+ * the kernel run from RAM. This requires relocating it, and since the
+ * RAM size isn't known, we can't use it for a stack. As a result,
+ * perform the relocation in assembly without using a stack.
+ */
+ ldr %r5, =(BOOT_RAM_START) /* Load RAM address in %r5 */
+ mov %r6, #0 /* Load kernel address in %r6 */
+ ldr %r0, boot_kernel_end /* Load kernel end virtual address
+ in %r0 */
+ ldr %r1, =(PMAP_START_KERNEL_ADDRESS) /* Load kernel virtual address in %r1 */
+ sub %r7, %r0, %r1 /* Compute kernel size in bytes */
+ lsr %r7, %r7, #2 /* Compute kernel size in words */
+
+ sub %r5, %r5, #4 /* Prepare for auto-increment */
+ sub %r6, %r6, #4
+
+1:
+ ldr %r0, [%r6, #4]! /* Load word with auto-increment */
+ str %r0, [%r5, #4]! /* Store word with auto-increment */
+ sub %r7, %r7, #4 /* Account for the written word */
+ cmp %r7, #0 /* Check the number of words left */
+ beq 1f /* Break if copy complete */
+ b 1b /* Continue otherwise */
+
+1:
+ /* TODO Invalidate all caches */
+
+ /* Set up the stack */
+ ldr %r13, boot_stack_addr
+ add %r13, %r13, #BOOT_STACK_SIZE
+
+ bl boot_setup_paging
+
+ /* Never reached */
+ nop
+
+ASM_END(_start)
+
+boot_kernel_end:
+ .long _end
+
+boot_stack_addr:
+ .long boot_stack
diff --git a/arch/arm/machine/cpu.h b/arch/arm/machine/cpu.h
index 80e11a05..d8b4c4d1 100644
--- a/arch/arm/machine/cpu.h
+++ b/arch/arm/machine/cpu.h
@@ -29,8 +29,23 @@
/*
* Data alignment, normally the word size.
+ *
+ * TODO Check.
+ */
+#define CPU_DATA_SHIFT 2
+#define CPU_DATA_ALIGN (1 << CPU_DATA_SHIFT)
+
+/*
+ * Function alignment.
+ *
+ * Aligning functions improves instruction fetching.
+ *
+ * Used for assembly functions only.
+ *
+ * XXX Use this value until processor selection is available.
*/
-#define CPU_DATA_ALIGN (LONG_BIT / 8)
+#define CPU_TEXT_SHIFT 4
+#define CPU_TEXT_ALIGN (1 << CPU_TEXT_SHIFT)
#ifndef __ASSEMBLER__
diff --git a/arch/arm/machine/pmap.h b/arch/arm/machine/pmap.h
index bae0c060..ecb3bf16 100644
--- a/arch/arm/machine/pmap.h
+++ b/arch/arm/machine/pmap.h
@@ -29,8 +29,6 @@
#define PMAP_START_DIRECTMAP_ADDRESS PMAP_END_ADDRESS
#define PMAP_END_DIRECTMAP_ADDRESS DECL_CONST(0xf8000000, UL)
-#define PMAP_KERNEL_OFFSET PMAP_START_DIRECTMAP_ADDRESS
-
#define PMAP_START_KMEM_ADDRESS PMAP_END_DIRECTMAP_ADDRESS
#define PMAP_END_KMEM_ADDRESS PMAP_END_KERNEL_ADDRESS
diff --git a/arch/arm/machine/tcb_asm.S b/arch/arm/machine/tcb_asm.S
new file mode 100644
index 00000000..f58f429e
--- /dev/null
+++ b/arch/arm/machine/tcb_asm.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Richard Braun.
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <machine/asm.h>
+
+ASM_FUNC(tcb_load):
+ASM_END(tcb_load)
diff --git a/arch/arm/x15.lds.S b/arch/arm/x15.lds.S
index a5c6cd3b..d867de29 100644
--- a/arch/arm/x15.lds.S
+++ b/arch/arm/x15.lds.S
@@ -7,11 +7,11 @@ ENTRY(_start)
#include <machine/boot.h>
#include <machine/cpu.h>
#include <machine/page.h>
-#include <machine/pmap.h>
PHDRS
{
/* Flags are actually similar to classic Unix permissions */
+ load PT_LOAD FLAGS(7);
boot PT_LOAD FLAGS(7);
init PT_LOAD FLAGS(7);
percpu PT_LOAD FLAGS(6);
@@ -22,22 +22,27 @@ PHDRS
SECTIONS
{
- . = BOOT_OFFSET;
+ . = 0;
+
+ .boot.load : {
+ *(BOOT_LOAD_SECTION)
+ } : load
+
+ . += BOOT_RAM_START;
_boot = .;
- .boot ALIGN(PAGE_SIZE) : {
- *(.boot.hdr)
- *(.boot.text)
- *(.boot.data)
+ .boot ALIGN(PAGE_SIZE) : AT(BOOT_RTOL(ADDR(.boot))) {
+ *(BOOT_TEXT_SECTION)
+ *(BOOT_DATA_SECTION)
} : boot
. = ALIGN(PAGE_SIZE);
_boot_end = .;
- . += PMAP_KERNEL_OFFSET;
+ . += (PMAP_START_KERNEL_ADDRESS - BOOT_RAM_START);
_init = .;
- .init ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.init))) {
+ .init ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.init))) {
*(.init.text)
*(.init.data)
@@ -52,7 +57,7 @@ SECTIONS
_init_end = .;
_percpu = .;
- .percpu 0 : AT(BOOT_VTOP(_percpu)) {
+ .percpu 0 : AT(BOOT_VTOL(_percpu)) {
*(.percpu)
} : percpu
@@ -61,32 +66,32 @@ SECTIONS
_percpu_end = .;
_text = .;
- .text ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.text))) {
+ .text ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.text))) {
*(.text)
} : text
. = ALIGN(PAGE_SIZE);
_rodata = .;
- .rodata ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.rodata))) {
+ .rodata ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.rodata))) {
*(.rodata)
} : rodata
- .notes ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOP(ADDR(.notes))) {
+ .notes ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOL(ADDR(.notes))) {
*(.note.*)
} : rodata
. = ALIGN(PAGE_SIZE);
_data = .;
- .data ALIGN(PAGE_SIZE) : AT(BOOT_VTOP(ADDR(.data))) {
+ .data ALIGN(PAGE_SIZE) : AT(BOOT_VTOL(ADDR(.data))) {
. = ALIGN(CPU_L1_SIZE);
*(.data.read_mostly)
. = ALIGN(CPU_L1_SIZE);
*(.data)
} : data
- .bss ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOP(ADDR(.bss))) {
+ .bss ALIGN(CPU_DATA_ALIGN) : AT(BOOT_VTOL(ADDR(.bss))) {
*(.bss)
} : data
diff --git a/arch/x86/machine/asm.h b/arch/x86/machine/asm.h
index 204d6fed..754c8f2f 100644
--- a/arch/x86/machine/asm.h
+++ b/arch/x86/machine/asm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012 Richard Braun.
+ * Copyright (c) 2011-2012 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _X86_ASM_H
-#define _X86_ASM_H
+#ifndef _ARM_ASM_H
+#define _ARM_ASM_H
#ifndef __ASSEMBLER__
#warning "asm.h included from a C file"
@@ -39,4 +39,4 @@ x:
#define ASM_END(x) \
.size x, . - x
-#endif /* _X86_ASM_H */
+#endif /* _ARM_ASM_H */