1/**
2 * \file
3 * \brief X86-64 address space sizes and offsets
4 *
5 * The layout of the x86-64 virtual address space can be summarized as
6 * follows:
7 *
8 *<pre>
9 * +----------------------------------------------------+-----------------+
10 * | User-space                                         | Physical memory |
11 * | PML4 entries: 0 1 2 3 4 ... 510                    | 511             |
12 * +----------------------------------------------------+-----------------+</pre>
13 *
14 * User-space maps user-space programs. Physical memory maps all
15 * available physical memory (up to PADDR_SPACE_LIMIT).
16 *
17 * This partition is static and can only be changed at compile-time.
18 *
19 * Physical memory can grow downwards, towards user-space, although it
20 * is expected to stay within PML4 entry 511 for quite some time (one
21 * PML4 entry can map 512 GBytes). The rest of the address space can
22 * be freely mapped by (possibly multiple) user-space programs.
23 */
24
25/*
26 * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
27 * All rights reserved.
28 *
29 * This file is distributed under the terms in the attached LICENSE file.
30 * If you do not find this file, copies can be found by writing to:
31 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
32 */
33
34#ifndef KERNEL_TARGET_X86_64_OFFSETS_H
35#define KERNEL_TARGET_X86_64_OFFSETS_H
36
37/**
38 * Absolute size of virtual address space. This is 48-bit on x86-64
39 * currently, which equals 256 TBytes and allows for 512 PML4 slots,
40 * each of which can map 512 GBytes.
41 */
42#define X86_64_VADDR_SPACE_BITS 48
43#define X86_64_VADDR_SPACE_SIZE        ((genpaddr_t)1 << X86_64_VADDR_SPACE_BITS)
44
45/**
46 * Absolute size of physical address space. This is also 48-bit.
47 */
48#define X86_64_PADDR_SPACE_BITS 48
49#define X86_64_PADDR_SPACE_SIZE        ((genpaddr_t)1 << X86_64_PADDR_SPACE_BITS)
50
51/**
52 * Start address of kernel image in physical memory. This is passed to
53 * the linker also. The bootloader will load us there.
54 */
55#define X86_64_START_KERNEL_PHYS       0x100000
56
57/**
58 * Kernel stack size -- 16KB
59 */
60#define X86_64_KERNEL_STACK_SIZE       0x4000
61
62/**
63 * Maximum physical address space mappable by the kernel.  Adjust this
64 * for a bigger physical address space.  We set this to 40-bit,
65 * i.e. 1 TByte.
66 */
67#define X86_64_PADDR_SPACE_LIMIT       ((genpaddr_t)1 << 40)
68
69/**
70 * Static address space limit for the init user-space domain. The
71 * static space is used to map in code and static data of the init
72 * module, as well as all loaded multiboot modules. init can freely
73 * allocate dynamic memory as soon as it is running. This is 32 MBytes
74 * right now.
75 *
76 * You should make this constant a multiple of #BASE_PAGE_SIZE *
77 * #PTABLE_SIZE or you'll restrict init's static address space
78 * unneccessarily. init's lowest segment should also be based at these
79 * multiples or it restricts itself.
80 */
81#define X86_64_INIT_SPACE_LIMIT        (32 * 1024 * 1024)
82
83/**
84 * Base address of init address space in virtual memory. init should
85 * start at 4 MByte. The kernel maps in important structures at 2
86 * MByte. This address should be page-table size aligned (i.e. with 4
87 * KByte pages, a page table maps 2 MBytes. Thus, align it to
88 * multiples of 2 MBytes).
89 */
90#define X86_64_INIT_VBASE              0x200000
91
92/**
93 * Initial amount of physical memory to map during bootup. The low
94 * 1MByte of memory is always expected to be there and has to be
95 * specified here at minimum. If you need more during bootup, increase
96 * this value. This value is also the amount of memory you _expect_ to
97 * be in the system during bootup, or the kernel will crash!
98 */
99#define X86_64_KERNEL_INIT_MEMORY      (1 * 1024 * 1024)
100
101/**
102 * Aligns an address to the nearest PML4 entry by masking out lower 41
103 * bits.
104 */
105#define X86_64_PML4_ALIGN(addr)        ((addr) & ((genpaddr_t)0x7fffff << 41))
106
107/**
108 * Absolute offset of mapped physical memory within virtual address
109 * space.  This occupies one or more (usually one) PML4 slots directly
110 * before the kernel. This needs to be aligned to PADDR_SPACE_LIMIT.
111 *
112 * Change VSPACE_END in lib/barrelfish if you change this.
113 */
114#define X86_64_MEMORY_OFFSET        X86_64_PML4_ALIGN(-X86_64_PADDR_SPACE_LIMIT)
115
116/**
117 * The real-mode addresses
118 */
119
120#define X86_64_REAL_MODE_SEGMENT 0x0600 /**< The real-mode segment */
121#define X86_64_REAL_MODE_OFFSET  0x0000 /**< The real-mode offset _has to be_ 0000!! */
122
123#define X86_64_REAL_MODE_LINEAR_OFFSET \
124    (X86_64_REAL_MODE_SEGMENT << 4) /**< The linear offset
125                                       of the real-mode
126                                       segment */
127
128#define X86_64_REAL_MODE_SEGMENT_TO_REAL_MODE_PAGE(seg) ((uint8_t)(seg >> 8))
129#define X86_64_REAL_MODE_ADDR_TO_REAL_MODE_VECTOR(seg,off) ((uint32_t)(seg << 16) | off)
130
131#ifndef __ASSEMBLER__
132
133/**
134 * \brief The kernel stack.
135 */
136extern uintptr_t x86_64_kernel_stack[X86_64_KERNEL_STACK_SIZE/sizeof(uintptr_t)];
137
138#endif
139
140#endif // KERNEL_TARGET_X86_64_OFFSETS_H
141