source: mainline/kernel/arch/arm64/src/mm/frame.c@ 84176f3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 84176f3 was 84176f3, checked in by Jakub Jermář <jakub@…>, 6 years ago

arm64: Add support for the architecture

This changeset adds basic support to run HelenOS on AArch64, targeting
the QEMU virt platform.

Boot:

  • Boot relies on the EDK II firmware, GRUB2 for EFI and the HelenOS bootloader (UEFI application). EDK II loads GRUB2 from a CD, GRUB2 loads the HelenOS bootloader (via UEFI) which loads OS components.
  • UEFI applications use the PE/COFF format and must be relocatable. The first problem is solved by manually having the PE/COFF headers and tables written in assembler. The relocatable requirement is addressed by compiling the code with -fpic and having the bootloader relocate itself at its startup.

Kernel:

  • Kernel code for AArch64 consists mostly of stubbing out various architecture-specific hooks: virtual memory management, interrupt and exception handling, context switching (including FPU lazy switching), support for virtual timer, atomic sequences and barriers, cache and TLB maintenance, thread and process initialization.
  • The patch adds a kernel driver for GICv2 (interrupt controller).
  • The PL011 kernel driver is extended to allow userspace to take ownership of the console.
  • The current code is not able to dynamically obtain information about available devices on the underlying machine. The port instead implements a machine-func interface similar to the one implemented by arm32. It defines a machine for the QEMU AArch64 virt platform. The configuration (device addresses and IRQ numbers) is then baked into the machine definition.

User space:

  • Uspace code for AArch64 similarly mostly implements architecture-specific hooks: context saving/restoring, syscall support, TLS support.

The patchset allows to boot the system but user interaction with the OS
is not yet possible.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 * Copyright (c) 2015 Petr Pavlu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_arm64_mm
30 * @{
31 */
32/** @file
33 * @brief Frame related functions.
34 */
35
36#include <arch/mm/frame.h>
37#include <mm/frame.h>
38#include <config.h>
39#include <align.h>
40#include <macros.h>
41
42/** Physical memory map received from the bootcode. */
43memmap_t memmap;
44
45/** Print memory layout. */
46void physmem_print(void)
47{
48 printf("[base ] [size ] [type ]\n");
49
50 size_t i;
51 for (i = 0; i < memmap.cnt; i++) {
52 const char *type;
53 switch (memmap.zones[i].type) {
54 case MEMTYPE_AVAILABLE:
55 type = "available";
56 break;
57 case MEMTYPE_ACPI_RECLAIM:
58 type = "ACPI reclaim";
59 break;
60 default:
61 type = "unusable";
62 break;
63 }
64
65 printf("%p %#018zx %s\n", memmap.zones[i].start,
66 memmap.zones[i].size, type);
67 }
68}
69
70/** Create memory zones according to information stored in memmap.
71 *
72 * Walk the memory map and create frame zones according to it.
73 */
74static void frame_common_arch_init(bool low)
75{
76 size_t i;
77
78 for (i = 0; i < memmap.cnt; i++) {
79 if (memmap.zones[i].type != MEMTYPE_AVAILABLE)
80 continue;
81
82 /* To be safe, make the available zone possibly smaller. */
83 uintptr_t base = ALIGN_UP((uintptr_t) memmap.zones[i].start,
84 FRAME_SIZE);
85 size_t size = ALIGN_DOWN(memmap.zones[i].size -
86 (base - (uintptr_t) memmap.zones[i].start), FRAME_SIZE);
87
88 if (!frame_adjust_zone_bounds(low, &base, &size))
89 continue;
90
91 pfn_t confdata;
92 pfn_t pfn = ADDR2PFN(base);
93 size_t count = SIZE2FRAMES(size);
94
95 if (low) {
96 /* Determine where to place confdata. */
97 if (pfn == 0) {
98 /*
99 * Avoid placing confdata at the NULL address.
100 */
101 if (count == 1)
102 continue;
103 confdata = 1;
104 } else
105 confdata = pfn;
106
107 zone_create(pfn, count, confdata,
108 ZONE_AVAILABLE | ZONE_LOWMEM);
109 } else {
110 confdata = zone_external_conf_alloc(count);
111 if (confdata != 0)
112 zone_create(pfn, count, confdata,
113 ZONE_AVAILABLE | ZONE_HIGHMEM);
114 }
115 }
116}
117
118/** Create low memory zones. */
119void frame_low_arch_init(void)
120{
121 if (config.cpu_active > 1)
122 return;
123
124 frame_common_arch_init(true);
125
126 /*
127 * On ARM64, physical memory can start on a non-zero address. The
128 * generic frame_init() only marks PFN 0 as not free, so we must mark
129 * the physically first frame not free explicitly here, no matter what
130 * is its address.
131 */
132 frame_mark_unavailable(ADDR2PFN(physmem_base), 1);
133}
134
135/** Create high memory zones. */
136void frame_high_arch_init(void)
137{
138 if (config.cpu_active > 1)
139 return;
140
141 frame_common_arch_init(false);
142}
143
144/** @}
145 */
Note: See TracBrowser for help on using the repository browser.