source: trunk/packages/xen-3.1/xen-3.1/extras/mini-os/arch/ia64/mm.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.0 KB
Line 
1/*
2 * Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
3 *
4 * Description: Special ia64 memory management.
5 * Parts are taken from FreeBSD.
6 *
7 ****************************************************************************
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to
11 * deal in the Software without restriction, including without limitation the
12 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
13 * sell copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28
29#include "os.h"
30#include "mm.h"
31
32
33#define MAX_MEM_AREA    5
34paddr_t phys_avail[MAX_MEM_AREA * 2];
35int     phys_avail_cnt;
36uint64_t physmem;
37
38/*
39 * These variables are defined in the linker script minios_ia64.lds
40 * to get the size of the kernel.
41 */
42extern uint64_t _text[], _etext[], _end[], kstack[], phys_start[];
43
44uint64_t kernstart, kernend, kernsize, kernpstart, kernpend;
45
46/* Print the available memory chunks. */
47static void
48print_phys_avail(void)
49{
50        int i;
51
52        printk("Physical memory chunk(s):\n");
53        for (i = 0; phys_avail[i + 1] != 0; i += 2) {
54                int size = phys_avail[i + 1] - phys_avail[i];
55                printk("0x%08lx - 0x%08lx, %d bytes (%d pages)\n",
56                        phys_avail[i], phys_avail[i + 1] - 1,
57                        size, size / PAGE_SIZE);
58        }
59}
60
61void
62arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
63{
64        uint64_t ms, me;
65        int i, j;
66        uint64_t m, n;
67
68        kernstart = trunc_page(_text);
69        kernend  = roundup_page(_end);
70
71        kernpstart = trunc_page(ia64_tpa(kernstart));
72        kernpend = roundup_page(kernpstart + (kernend - kernstart));
73        kernsize = kernpend - kernpstart;
74
75        ms = roundup_page(machineFwG.mach_mem_start);
76        me = trunc_page(machineFwG.mach_mem_start+machineFwG.mach_mem_size);
77        memset((void*)phys_avail, 0, sizeof(phys_avail));
78        /* 1. Check where the kernel lies in physical memory. */
79        physmem = me - ms;
80        if ((ms <= kernpend) && (kernpstart <= me)) {
81                if (ms < kernpstart) {  /* There is a part before the kernel. */
82                        PRINT_BV("  Found chunk before kernel: 0x%lx - 0x%lx\n",
83                                 ms, kernpstart);
84                        phys_avail[phys_avail_cnt] = ms;
85                        phys_avail[phys_avail_cnt+1] = kernpstart;
86                        phys_avail_cnt += 2;
87                }
88                if (kernpend < me) {    /* There is a part behind the kernel. */
89                        PRINT_BV("  Found chunk behind kernel: 0x%lx - 0x%lx\n",
90                                 kernpend, me);
91                        phys_avail[phys_avail_cnt] = kernpend;
92                        phys_avail[phys_avail_cnt+1] = me;
93                        phys_avail_cnt += 2;
94                }
95        } else {        /* One big chunk */
96                PRINT_BV("  Found big chunk: 0x%lx - 0x%lx\n", ms, me);
97                phys_avail[phys_avail_cnt] = ms;
98                phys_avail[phys_avail_cnt + 1] = me;
99                phys_avail_cnt += 2;
100        }
101        phys_avail[phys_avail_cnt] = 0;
102
103        print_phys_avail();
104        /*
105         * In this first version I only look for the biggest mem area.
106         */
107        for (i = j = m = n = 0; i < phys_avail_cnt; i += 2) {
108                n = page_to_pfn(phys_avail[i + 1]) - page_to_pfn(phys_avail[i]);
109                if (n > m) {
110                        m = n;
111                        j = i;
112                }
113        }
114        *start_pfn_p = page_to_pfn(phys_avail[j]);
115        *max_pfn_p   = page_to_pfn(phys_avail[j +1 ]);
116}
117
118/* Currently only a dummy function. */
119void
120arch_init_demand_mapping_area(unsigned long max_pfn)
121{
122        max_pfn = max_pfn;
123}
124
125/* Helper function used in gnttab.c. */
126void*
127map_frames(unsigned long* frames, unsigned long n)
128{
129        n = n;
130        return (void*) __va(SWAP(frames[0]) << PAGE_SHIFT);
131}
132
133void arch_init_p2m(unsigned long max_pfn)
134{
135    printk("Warn: p2m map not implemented.\n");
136}
Note: See TracBrowser for help on using the repository browser.