Imported Upstream version 3.14
[debian/elilo] / ia64 / system.c
1 /*
2  *  Copyright (C) 2001-2003 Hewlett-Packard Co.
3  *      Contributed by Stephane Eranian <eranian@hpl.hp.com>
4  *
5  * This file is part of the ELILO, the EFI Linux boot loader.
6  *
7  *  ELILO is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2, or (at your option)
10  *  any later version.
11  *
12  *  ELILO is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with ELILO; see the file COPYING.  If not, write to the Free
19  *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20  *  02111-1307, USA.
21  *
22  * Please check out the elilo.txt for complete documentation on how
23  * to use this program.
24  */
25
26 /*
27  * this file contains all the IA-64 specific code expected by generic loader
28  */
29 #include <efi.h>
30 #include <efilib.h>
31
32 #include "elilo.h"
33 #include "loader.h"
34 #include "private.h"
35
36 extern loader_ops_t plain_loader, gzip_loader;
37
38 /*
39  * IA-64 specific boot paramters initialization routine
40  */
41 INTN
42 sysdeps_create_boot_params(boot_params_t *bp, CHAR8 *cmdline, memdesc_t *initrd, memdesc_t *vmcode, UINTN *cookie)
43 {
44         UINTN cols, rows;
45         SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
46         EFI_STATUS status;
47         mmap_desc_t mdesc;
48
49         /*
50          * retrieve address of FPSWA interface
51          * if not found, argument is not touched
52          * will be 0 because of Memset()
53          */
54         query_fpswa((VOID **)&bp->fpswa);
55
56         if (get_memmap(&mdesc) == -1) return -1;
57
58         DBG_PRT((L"Got memory map @ 0x%lx (%d bytes) with key %d", mdesc.md, mdesc.map_size, mdesc.cookie));
59
60         bp->efi_systab          = (UINTN)systab;
61         bp->efi_memmap          = (UINTN)mdesc.md;
62         bp->efi_memmap_size     = mdesc.map_size;
63         bp->efi_memdesc_size    = mdesc.desc_size;
64         bp->efi_memdesc_version = mdesc.desc_version;
65         bp->command_line        = (UINTN)cmdline;
66         bp->initrd_start        = (UINTN) initrd->start_addr;
67         bp->initrd_size         = initrd->size;
68         DBG_PRT((L"Got initrd @ 0x%lx (%d bytes)", initrd->start_addr, initrd->size));
69
70         bp->vmcode_start        = (UINTN) vmcode->start_addr;
71         bp->vmcode_size         = vmcode->size;
72         DBG_PRT((L"Got vmcode @ 0x%lx (%d bytes)", vmcode->start_addr, vmcode->size));
73
74         /* fetch console parameters: */
75         conout = systab->ConOut;
76         status = conout->QueryMode(conout, conout->Mode->Mode, &cols, &rows);
77         if (EFI_ERROR(status)) {
78                 ERR_PRT((L"boot_params QueryMode failed %r", status));
79                 goto error;
80         }
81         DBG_PRT((L"Got console info: cols=%d rows=%d x=%d y=%d",
82               cols, rows, conout->Mode->CursorColumn, conout->Mode->CursorRow));
83
84         bp->console_info.num_cols = cols;
85         bp->console_info.num_rows = rows;
86         bp->console_info.orig_x = conout->Mode->CursorColumn;
87         bp->console_info.orig_y = conout->Mode->CursorRow;
88
89         *cookie = mdesc.cookie;
90
91         return 0;
92 error:
93         /* free descriptors' memory */
94         free_memmap(&mdesc);
95
96         return -1;
97 }
98
99 VOID
100 sysdeps_free_boot_params(boot_params_t *bp)
101 {
102         mmap_desc_t md;
103
104         Memset(&md, 0, sizeof(md));
105
106         md.md = (VOID *)bp->efi_memmap;
107
108         free_memmap(&md);
109 }
110
111 INTN
112 sysdeps_init(EFI_HANDLE dev)
113 {
114         loader_register(&plain_loader);
115         loader_register(&gzip_loader);
116
117         return 0;
118 }
119
120 INTN
121 sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
122 {
123         /*
124          * We currently place the initrd at the next page aligned boundary
125          * after the kernel. 
126          *
127          * Current kernel implementation requires this (see arch/ia64/kernel/setup.c).
128          *
129          * IMPORTANT: EFI & kernel page sizes may differ. We have no way
130          * of guessing what size the kernel uses. It is the responsibility
131          * of the kernel to adjust.
132          *
133          */
134 #if 0
135         imem->start_addr = (VOID *)ROUNDUP((UINTN)kd->kend, EFI_PAGE_SIZE);
136 #else
137         imem->start_addr = 0; /* let the allocator decide */
138 #endif
139
140         return 0;
141 }
142
143 VOID *
144 sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
145 {
146         return start_addr;
147 }
148
149 /* Flush data cache [addr; addr + len], and sync with icache.  */
150 void
151 flush_dcache (CHAR8 *addr, UINT64 len)
152 {
153         /* Cache line length is at least 32.  */
154         UINT64 a = (UINT64)addr & ~0x1f;
155
156         DBG_PRT((L"Flush 0x%lx-", a));
157
158         /* Flush data.  */
159         for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20)
160                 asm volatile ("fc %0" : : "r" (a));
161         /* Sync and serialize.  Maybe extra.  */
162         asm volatile (";; sync.i;; srlz.i;;");
163
164         DBG_PRT((L"0x%lx\n", a));
165 }