1/**
2 * \file
3 * \brief ARMv8 address-space sizes and offsets
4 *
5 */
6
7/*
8 * Copyright (c) 2007,2008,2009,2012,2015,2016 ETH Zurich.
9 * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
10 * All rights reserved.
11 *
12 * This file is distributed under the terms in the attached LICENSE file.
13 * If you do not find this file, copies can be found by writing to:
14 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
15 */
16
17#ifndef OFFSETS_H
18#define OFFSETS_H
19
20#define GEN_ADDR(bits)          (((genpaddr_t)1) << bits)
21
22/**
23 * Absolute size of virtual address space. This is 48-bit on AArch64.
24 * TODO: might be implementation-specific
25 */
26#define VADDR_SPACE_SIZE_BITS   48
27#define VADDR_SPACE_SIZE        GEN_ADDR(VADDR_SPACE_SIZE_BITS);
28
29/**
30 * Absolute size of physical address space.
31 * Depends on value in ID_AA64MMFR0_EL1 (ARMv8-A TRM, D4-1733)
32 * current options are 4G, 64G, 1T, 4T, 16T, 256T
33 * set to 256T for now
34 */
35#define PADDR_SPACE_SIZE_BITS   48
36#define PADDR_SPACE_SIZE        GEN_ADDR(PADDR_SPACE_SIZE_BITS)
37
38/**
39 * Start address of kernel image in physical memory.  Most ARM platforms have
40 * the first physical window starting at 2GB.
41 */
42#define START_KERNEL_PHYS       0x80000000
43
44/**
45 * Kernel offset - virtual base of the kernel's address space: the region
46 * mapped by TTBR1.
47 */
48#define KERNEL_OFFSET           0xffff000000000000ULL
49
50/**
51 * Maximum physical address space mappable by the kernel.  Adjust this
52 * for a bigger physical address space.
53 */
54#define PADDR_SPACE_LIMIT       (GEN_ADDR(49) - 1) // 2GB
55
56/**
57 * Static address space limit for the init user-space domain. The
58 * static space is used to map in code and static data of the init
59 * module, as well as all loaded multiboot modules. init can freely
60 * allocate dynamic memory as soon as it is running. This is 32 MBytes
61 * right now.
62 *
63 * You should make this constant a multiple of #BASE_PAGE_SIZE *
64 * #PTABLE_SIZE or you'll restrict init's static address space
65 * unneccessarily. init's lowest segment should also be based at these
66 * multiples or it restricts itself.
67 *
68 */
69#define ARMV8_INIT_SPACE_LIMIT        (32 * 1024 * 1024)
70
71/**
72 * Base address of init address space in virtual memory. init should
73 * start at 4 MByte. The kernel maps in important structures at 2
74 * MByte. This address should be page-table size aligned (i.e. with 4
75 * KByte pages, a page table maps 2 MBytes. Thus, align it to
76 * multiples of 2 MBytes).
77 */
78#define ARMV8_INIT_VBASE              (2 * 1024 * 1024)
79
80/**
81 * The absolute base address of mapped physical memory, within the kernel's
82 * virtual address space.
83 *
84 */
85#define MEMORY_OFFSET           (KERNEL_OFFSET)
86
87/**
88 * Absolute start of RAM in physical memory.  XXX - this isn't statically
89 * known.
90 */
91#define PHYS_MEMORY_START       0x0
92
93/*
94 * The top of the region, within kernel memory, in which devices are mapped.
95 */
96#define DEVICE_OFFSET           (KERNEL_OFFSET + GEN_ADDR(30))
97
98/**
99 * Kernel stack size -- 16KB
100 */
101#define KERNEL_STACK_SIZE       0x4000
102
103/**
104 * The size of the whole kernel image.
105 */
106#define KERNEL_IMAGE_SIZE       (size_t)(&kernel_final_byte - \
107                                         &kernel_first_byte)
108
109/*
110 * Bytes per kernel copy for each core (1 Section)
111 */
112#define KERNEL_SECTION_SIZE     0x100000
113
114#define KERNEL_STACK_ADDR       (lpaddr_t)kernel_stack
115
116#ifndef __ASSEMBLER__
117
118#include <assert.h>
119#include <stdbool.h>
120
121static inline lvaddr_t local_phys_to_mem(lpaddr_t addr)
122{
123    assert(addr < PHYS_MEMORY_START + PADDR_SPACE_LIMIT);
124    return (lvaddr_t)(addr + ((lpaddr_t)MEMORY_OFFSET -
125                              (lpaddr_t)PHYS_MEMORY_START));
126}
127
128/**
129 * Checks whether absolute local physical address `addr` is valid.
130 * \param addr Absolute local physical address
131 * \return True iff addr is a valid local physical address
132 */
133static inline bool local_phys_is_valid(lpaddr_t addr)
134{
135    return addr < PHYS_MEMORY_START + PADDR_SPACE_LIMIT;
136}
137
138static inline lpaddr_t mem_to_local_phys(lvaddr_t addr)
139{
140    assert(addr >= MEMORY_OFFSET);
141    return (lpaddr_t)(addr - ((lvaddr_t)MEMORY_OFFSET -
142                              (lvaddr_t)PHYS_MEMORY_START));
143}
144
145static inline lpaddr_t gen_phys_to_local_phys(genpaddr_t addr)
146{
147    //assert(addr < PADDR_SPACE_SIZE);
148    return (lpaddr_t)addr;
149}
150
151/* XXX - what is this? */
152static inline genpaddr_t local_phys_to_gen_phys(lpaddr_t addr)
153{
154    return (genpaddr_t)addr;
155}
156
157/**
158 * Symbol: Start of kernel image. This symbol points to the start
159 * address of the kernel image.
160 */
161extern uint8_t kernel_first_byte;
162
163/**
164 * Symbol: End of kernel image. This symbol points to the end address
165 * of the kernel image.
166 */
167extern uint8_t kernel_text_final_byte;
168
169/**
170 * Symbol: End of kernel image. This symbol points to the end address
171 * of the kernel image.
172 */
173extern uint8_t kernel_final_byte;
174
175extern uint8_t kernel_elf_header;
176
177/**
178 * \brief The kernel stack.
179 *
180 * Declared in boot.S.
181 */
182extern uintptr_t kernel_stack, kernel_stack_top;
183
184#endif  // __ASSEMBLER__
185
186#endif  // OFFSETS_H
187