From: Thomas Leonard <talex5@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Thomas Leonard <talex5@gmail.com>,
Dave.Scott@eu.citrix.com, anil@recoil.org,
stefano.stabellini@eu.citrix.com, samuel.thibault@ens-lyon.org
Subject: [PATCH ARM v7 05/13] mini-os: arm: boot code
Date: Fri, 8 Aug 2014 16:47:34 +0100 [thread overview]
Message-ID: <1407512862-9373-6-git-send-email-talex5@gmail.com> (raw)
In-Reply-To: <1407512862-9373-1-git-send-email-talex5@gmail.com>
Based on an initial patch by Karim Raslan.
Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>
---
Changes since v6:
- Fixed printk format types.
Addressed Ian Campbell's comments:
- ARMv7 A8.8.247 says udf should not be used conditionally, so use
a branch instead.
- Enable caching earlier (required setting the cacheability for the
translation table walks).
- Added some extra dsb instructions to protect against reordering.
Addressed Julien Grall's comments:
- Note that TTBCR is zero (using short-descriptors, TTBR0 only).
- Note about relying on 0x8000 load offset.
---
| 211 +++++++++++++++++++++++++++++++
| 64 ++++++++++
| 83 ++++++++++++
| 119 +++++++++++++++++
4 files changed, 477 insertions(+)
create mode 100644 extras/mini-os/arch/arm/arm32.S
create mode 100644 extras/mini-os/arch/arm/hypercalls32.S
create mode 100755 extras/mini-os/arch/arm/minios-arm32.lds
create mode 100644 extras/mini-os/arch/arm/setup.c
--git a/extras/mini-os/arch/arm/arm32.S b/extras/mini-os/arch/arm/arm32.S
new file mode 100644
index 0000000..d2e6932
--- /dev/null
+++ b/extras/mini-os/arch/arm/arm32.S
@@ -0,0 +1,211 @@
+@ Offset of the kernel within the RAM. This is a Linux/zImage convention which we
+@ rely on for now.
+#define ZIMAGE_KERNEL_OFFSET 0x8000
+
+.section .text
+
+.globl _start
+_start:
+ @ zImage header
+.rept 8
+ mov r0, r0
+.endr
+ b reset
+ .word 0x016f2818 @ Magic numbers to help the loader
+ .word 0 @ zImage start address (0 = relocatable)
+ .word _edata - _start @ zImage end address (excludes bss section)
+ @ end of zImage header
+
+@ Called at boot time. Sets up MMU, exception vectors and stack, and then calls C arch_init() function.
+@ => r2 -> DTB
+@ <= never returns
+@ Note: this boot code needs to be within the first (1MB - ZIMAGE_KERNEL_OFFSET) of _start.
+reset:
+ @ Problem: the C code wants to be at a known address (_start), but Xen might
+ @ load us anywhere. We initialise the MMU (mapping virtual to physical @ addresses)
+ @ so everything ends up where the code expects it to be.
+ @
+ @ We calculate the offet between where the linker thought _start would be and where
+ @ it actually is and initialise the page tables to have that offset for every page.
+ @
+ @ When we turn on the MMU, we're still executing at the old address. We don't want
+ @ the code to disappear from under us. So we have to do the mapping in stages:
+ @
+ @ 1. set up a mapping to our current page from both its current and desired addresses
+ @ 2. enable the MMU
+ @ 3. jump to the new address
+ @ 4. remap all the other pages with the calculated offset
+
+ adr r1, _start @ r1 = physical address of _start
+ ldr r3, =_start @ r3 = (desired) virtual address of _start
+ sub r9, r1, r3 @ r9 = (physical - virtual) offset
+
+ ldr r7, =_page_dir @ r7 = (desired) virtual addr of translation table
+ add r1, r7, r9 @ r1 = physical addr of translation table
+
+ @ Tell the system where our page table is located.
+ @ This is the 16 KB top-level translation table, in which
+ @ each word maps one 1MB virtual section to a physical section.
+ @ Note: We leave TTBCR as 0, meaning that only TTBR0 is used and
+ @ we use the short-descriptor format (32-bit physical addresses).
+ orr r0, r1, #0b0001011 @ Sharable, Inner/Outer Write-Back Write-Allocate Cacheable
+ mcr p15, 0, r0, c2, c0, 0 @ set TTBR0
+
+ @ Set access permission for domains.
+ @ Domains are deprecated, but we have to configure them anyway.
+ @ We mark every page as being domain 0 and set domain 0 to "client mode"
+ @ (client mode = use access flags in page table).
+ mov r0, #1 @ 1 = client
+ mcr p15, 0, r0, c3, c0, 0 @ DACR
+
+ @ Template (flags) for a 1 MB page-table entry.
+ @ TEX[2:0] C B = 001 1 1 (outer and inner write-back, write-allocate)
+ ldr r8, =(0x2 + /* Section entry */ \
+ 0xc + /* C B */ \
+ (3 << 10) + /* Read/write */ \
+ (1 << 12) + /* TEX */ \
+ (1 << 16) + /* Sharable */ \
+ (1<<19)) /* Non-secure */
+ @ r8 = template page table entry
+
+ @ Add an entry for the current physical section, at the old and new
+ @ addresses. It's OK if they're the same.
+ mov r0, pc, lsr#20
+ mov r0, r0, lsl#20 @ r0 = physical address of this code's section start
+ orr r3, r0, r8 @ r3 = table entry for this section
+ ldr r4, =_start @ r4 = desired virtual address of this section
+ str r3, [r1, r4, lsr#18] @ map desired virtual section to this code
+ str r3, [r1, r0, lsr#18] @ map current section to this code too
+
+ @ Invalidate TLB
+ dsb @ Caching is off, but must still prevent reordering
+ mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
+
+ @ Enable MMU / SCTLR
+ mrc p15, 0, r1, c1, c0, 0 @ SCTLR
+ orr r1, r1, #3 << 11 @ enable icache, branch prediction
+ orr r1, r1, #4 + 1 @ enable dcache, MMU
+ mcr p15, 0, r1, c1, c0, 0 @ SCTLR
+ isb
+
+ ldr r1, =stage2 @ Virtual address of stage2
+ bx r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@ r7 = virtual address of page table
+@ r8 = section entry template (flags)
+@ r9 = desired physical - virtual offset
+@ pc -> somewhere in newly-mapped virtual code section
+stage2:
+ @ Invalidate TLB
+ mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
+ isb
+
+ @ The new mapping has now taken effect:
+ @ r7 -> page_dir
+
+ @ Fill in the whole top-level translation table (at page_dir).
+ @ Populate the whole pagedir with 1MB section descriptors.
+
+ mov r1, r7 @ r1 -> first section entry
+ add r3, r1, #4*4*1024 @ limit (4 GB address space, 4 byte entries)
+ orr r0, r8, r9 @ r0 = entry mapping section zero to start of physical RAM
+1:
+ str r0, [r1],#4 @ write the section entry
+ add r0, r0, #1 << 20 @ next physical page (wraps)
+ cmp r1, r3
+ bne 1b
+
+ @ Invalidate TLB
+ dsb
+ mcr p15, 0, r1, c8, c7, 0 @ TLBIALL
+ isb
+
+ @ Set VBAR -> exception_vector_table
+ @ SCTLR.V = 0
+ adr r0, exception_vector_table
+ mcr p15, 0, r0, c12, c0, 0
+
+ @ Enable hardware floating point:
+ @ 1. Access to CP10 and CP11 must be enabled in the Coprocessor Access
+ @ Control Register (CP15.CACR):
+ mrc p15, 0, r1, c1, c0, 2 @ CACR
+ orr r1, r1, #(3 << 20) + (3 << 22) @ full access for CP10 & CP11
+ mcr p15, 0, r1, c1, c0, 2
+ @ 2. The EN bit in the FPEXC register must be set:
+ vmrs r0, FPEXC
+ orr r0, r0, #1<<30 @ EN (enable)
+ vmsr FPEXC, r0
+
+ @ Initialise 16 KB stack
+ ldr sp, =_boot_stack_end
+
+ sub r0, r2, r9 @ r0 -> device tree (virtual address)
+ mov r1, r9 @ r1 = physical_address_offset
+
+ b arch_init
+
+.pushsection .bss
+@ Note: calling arch_init zeroes out this region.
+.align 12
+.globl shared_info_page
+shared_info_page:
+ .fill (1024), 4, 0x0
+
+.align 3
+.globl irqstack
+.globl irqstack_end
+irqstack:
+ .fill (1024), 4, 0x0
+irqstack_end:
+
+.popsection
+
+@ exception base address
+.align 5
+.globl exception_vector_table
+@ Note: remember to call CLREX if returning from an exception:
+@ "The architecture enables the local monitor to treat any exclusive store as
+@ matching a previous LDREX address. For this reason, use of the CLREX
+@ instruction to clear an existing tag is required on context switches."
+@ -- ARM Cortex-A Series Programmer’s Guide (Version: 4.0)
+exception_vector_table:
+ b . @ reset
+ b . @ undefined instruction
+ b . @ supervisor call
+ b . @ prefetch call
+ b . @ prefetch abort
+ b . @ data abort
+ b irq_handler @ irq
+ .word 0xe7f000f0 @ abort on FIQ
+
+@ Call fault_undefined_instruction in "Undefined mode"
+bug:
+ .word 0xe7f000f0 @ und/udf - a "Permanently Undefined" instruction
+
+irq_handler:
+ ldr sp, =irqstack_end
+ push {r0 - r12, r14}
+
+ ldr r0, IRQ_handler
+ cmp r0, #0
+ beq bug
+ blx r0 @ call handler
+
+ @ Return from IRQ
+ pop {r0 - r12, r14}
+ clrex
+ subs pc, lr, #4
+
+.globl IRQ_handler
+IRQ_handler:
+ .long 0x0
+
+@ This is called if you try to divide by zero. For now, we make a supervisor call,
+@ which will make us halt.
+.globl raise
+raise:
+ svc 0
--git a/extras/mini-os/arch/arm/hypercalls32.S b/extras/mini-os/arch/arm/hypercalls32.S
new file mode 100644
index 0000000..af8e175
--- /dev/null
+++ b/extras/mini-os/arch/arm/hypercalls32.S
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <xen/xen.h>
+
+#define __HVC(imm16) .long ((0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F)) & 0xFFFFFFFF)
+
+#define XEN_IMM 0xEA1
+
+#define HYPERCALL_SIMPLE(hypercall) \
+.globl HYPERVISOR_##hypercall; \
+.align 4,0x90; \
+HYPERVISOR_##hypercall: \
+ mov r12, #__HYPERVISOR_##hypercall; \
+ __HVC(XEN_IMM); \
+ mov pc, lr;
+
+#define _hypercall0 HYPERCALL_SIMPLE
+#define _hypercall1 HYPERCALL_SIMPLE
+#define _hypercall2 HYPERCALL_SIMPLE
+#define _hypercall3 HYPERCALL_SIMPLE
+#define _hypercall4 HYPERCALL_SIMPLE
+
+_hypercall2(sched_op);
+_hypercall2(memory_op);
+_hypercall2(event_channel_op);
+_hypercall2(xen_version);
+_hypercall3(console_io);
+_hypercall1(physdev_op);
+_hypercall3(grant_table_op);
+_hypercall3(vcpu_op);
+_hypercall1(sysctl);
+_hypercall1(domctl);
+_hypercall2(hvm_op);
+_hypercall1(xsm_op);
--git a/extras/mini-os/arch/arm/minios-arm32.lds b/extras/mini-os/arch/arm/minios-arm32.lds
new file mode 100755
index 0000000..9627162
--- /dev/null
+++ b/extras/mini-os/arch/arm/minios-arm32.lds
@@ -0,0 +1,83 @@
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /* Note: we currently assume that Xen will load the kernel image
+ * at start-of-RAM + 0x8000. We use this initial 32 KB for the stack
+ * and translation tables.
+ */
+ _boot_stack = 0x400000; /* 16 KB boot stack */
+ _boot_stack_end = 0x404000;
+ _page_dir = 0x404000; /* 16 KB translation table */
+ . = 0x408000;
+ _text = .; /* Text and read-only data */
+ .text : {
+ *(.text)
+ *(.gnu.warning)
+ } = 0x9090
+
+ _etext = .; /* End of text section */
+
+ .rodata : { *(.rodata) *(.rodata.*) }
+ . = ALIGN(4096);
+ _erodata = .;
+
+ /* newlib initialization functions */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { *(.preinit_array) }
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { *(.init_array) }
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { *(.fini_array) }
+ PROVIDE (__fini_array_end = .);
+
+ .ctors : {
+ __CTOR_LIST__ = .;
+ *(.ctors)
+ CONSTRUCTORS
+ LONG(0)
+ __CTOR_END__ = .;
+ }
+
+ .dtors : {
+ __DTOR_LIST__ = .;
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ }
+
+ .data : { /* Data */
+ *(.data)
+ }
+
+ /* Note: linker will insert any extra sections here, just before .bss */
+
+ .bss : {
+ _edata = .; /* End of data included in image */
+ /* Nothing after here is included in the zImage's size */
+
+ __bss_start = .;
+ *(.bss)
+ *(.app.bss)
+ }
+ _end = . ;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.text.exit)
+ *(.data.exit)
+ *(.exitcall.exit)
+ }
+
+ /* 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) }
+}
--git a/extras/mini-os/arch/arm/setup.c b/extras/mini-os/arch/arm/setup.c
new file mode 100644
index 0000000..06afe46
--- /dev/null
+++ b/extras/mini-os/arch/arm/setup.c
@@ -0,0 +1,119 @@
+#include <mini-os/os.h>
+#include <mini-os/kernel.h>
+#include <mini-os/gic.h>
+#include <mini-os/console.h>
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xen/hvm/params.h>
+#include <arch_mm.h>
+#include <libfdt.h>
+
+/*
+ * This structure contains start-of-day info, such as pagetable base pointer,
+ * address of the shared_info structure, and things like that.
+ * On x86, the hypervisor passes it to us. On ARM, we fill it in ourselves.
+ */
+union start_info_union start_info_union;
+
+/*
+ * Shared page for communicating with the hypervisor.
+ * Events flags go here, for example.
+ */
+shared_info_t *HYPERVISOR_shared_info;
+
+extern char shared_info_page[PAGE_SIZE];
+
+void *device_tree;
+
+static int hvm_get_parameter(int idx, uint64_t *value)
+{
+ struct xen_hvm_param xhv;
+ int ret;
+
+ xhv.domid = DOMID_SELF;
+ xhv.index = idx;
+ ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+ if (ret < 0) {
+ BUG();
+ }
+ *value = xhv.value;
+ return ret;
+}
+
+static void get_console(void)
+{
+ uint64_t v = -1;
+
+ hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
+ start_info.console.domU.evtchn = v;
+
+ hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
+ start_info.console.domU.mfn = v;
+
+ printk("Console is on port %d\n", start_info.console.domU.evtchn);
+ printk("Console ring is at mfn %lx\n", (unsigned long) start_info.console.domU.mfn);
+}
+
+void get_xenbus(void)
+{
+ uint64_t value;
+
+ if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &value))
+ BUG();
+
+ start_info.store_evtchn = (int)value;
+
+ if(hvm_get_parameter(HVM_PARAM_STORE_PFN, &value))
+ BUG();
+ start_info.store_mfn = (unsigned long)value;
+}
+
+/*
+ * INITIAL C ENTRY POINT.
+ */
+void arch_init(void *dtb_pointer, uint32_t physical_offset)
+{
+ struct xen_add_to_physmap xatp;
+ int r;
+
+ memset(&__bss_start, 0, &_end - &__bss_start);
+
+ physical_address_offset = physical_offset;
+
+ xprintk("Virtual -> physical offset = %x\n", physical_address_offset);
+
+ xprintk("Checking DTB at %p...\n", dtb_pointer);
+
+ if ((r = fdt_check_header(dtb_pointer))) {
+ xprintk("Invalid DTB from Xen: %s\n", fdt_strerror(r));
+ BUG();
+ }
+ device_tree = dtb_pointer;
+
+ /* Map shared_info page */
+ xatp.domid = DOMID_SELF;
+ xatp.idx = 0;
+ xatp.space = XENMAPSPACE_shared_info;
+ xatp.gpfn = virt_to_pfn(shared_info_page);
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
+ BUG();
+ HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+ /* Fill in start_info */
+ get_console();
+ get_xenbus();
+
+ gic_init();
+
+ start_kernel();
+}
+
+void
+arch_fini(void)
+{
+}
+
+void
+arch_do_exit(void)
+{
+}
--
2.0.3
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2014-08-08 15:47 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 02/13] mini-os: added HYPERVISOR_xsm_op Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c Thomas Leonard
2014-08-08 16:37 ` Samuel Thibault
2014-08-11 7:59 ` Thomas Leonard
2014-08-11 9:29 ` Samuel Thibault
2014-08-28 15:07 ` Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 04/13] mini-os: arm: add header files Thomas Leonard
2014-08-08 15:47 ` Thomas Leonard [this message]
2014-08-08 15:47 ` [PATCH ARM v7 06/13] mini-os: arm: memory management Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 07/13] mini-os: arm: scheduling Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 08/13] mini-os: arm: events Thomas Leonard
2014-09-08 11:52 ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 09/13] mini-os: arm: time Thomas Leonard
2014-09-08 10:59 ` Ian Campbell
2014-09-08 16:08 ` Thomas Leonard
2014-09-22 10:35 ` Dave Scott
2014-09-23 16:53 ` Stefano Stabellini
2014-09-26 10:01 ` Thomas Leonard
2014-10-01 11:10 ` Thomas Leonard
2014-10-01 11:10 ` Thomas Leonard
2014-10-01 11:31 ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 10/13] mini-os: arm: interrupt controller Thomas Leonard
2014-09-08 11:01 ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 11/13] mini-os: arm: build system Thomas Leonard
2014-09-08 11:05 ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault Thomas Leonard
2014-09-08 11:06 ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n Thomas Leonard
2014-09-08 11:08 ` Ian Campbell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1407512862-9373-6-git-send-email-talex5@gmail.com \
--to=talex5@gmail.com \
--cc=Dave.Scott@eu.citrix.com \
--cc=anil@recoil.org \
--cc=samuel.thibault@ens-lyon.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.