OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [x86/] [kernel/] [efi_32.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Extensible Firmware Interface
3
 *
4
 * Based on Extensible Firmware Interface Specification version 1.0
5
 *
6
 * Copyright (C) 1999 VA Linux Systems
7
 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
8
 * Copyright (C) 1999-2002 Hewlett-Packard Co.
9
 *      David Mosberger-Tang <davidm@hpl.hp.com>
10
 *      Stephane Eranian <eranian@hpl.hp.com>
11
 *
12
 * All EFI Runtime Services are not implemented yet as EFI only
13
 * supports physical mode addressing on SoftSDV. This is to be fixed
14
 * in a future version.  --drummond 1999-07-20
15
 *
16
 * Implemented EFI runtime services and virtual mode calls.  --davidm
17
 *
18
 * Goutham Rao: <goutham.rao@intel.com>
19
 *      Skip non-WB memory and ignore empty memory ranges.
20
 */
21
 
22
#include <linux/kernel.h>
23
#include <linux/init.h>
24
#include <linux/mm.h>
25
#include <linux/types.h>
26
#include <linux/time.h>
27
#include <linux/spinlock.h>
28
#include <linux/bootmem.h>
29
#include <linux/ioport.h>
30
#include <linux/module.h>
31
#include <linux/efi.h>
32
#include <linux/kexec.h>
33
 
34
#include <asm/setup.h>
35
#include <asm/io.h>
36
#include <asm/page.h>
37
#include <asm/pgtable.h>
38
#include <asm/processor.h>
39
#include <asm/desc.h>
40
#include <asm/tlbflush.h>
41
 
42
#define EFI_DEBUG       0
43
#define PFX             "EFI: "
44
 
45
extern efi_status_t asmlinkage efi_call_phys(void *, ...);
46
 
47
struct efi efi;
48
EXPORT_SYMBOL(efi);
49
static struct efi efi_phys;
50
struct efi_memory_map memmap;
51
 
52
/*
53
 * We require an early boot_ioremap mapping mechanism initially
54
 */
55
extern void * boot_ioremap(unsigned long, unsigned long);
56
 
57
/*
58
 * To make EFI call EFI runtime service in physical addressing mode we need
59
 * prelog/epilog before/after the invocation to disable interrupt, to
60
 * claim EFI runtime service handler exclusively and to duplicate a memory in
61
 * low memory space say 0 - 3G.
62
 */
63
 
64
static unsigned long efi_rt_eflags;
65
static DEFINE_SPINLOCK(efi_rt_lock);
66
static pgd_t efi_bak_pg_dir_pointer[2];
67
 
68
static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
69
{
70
        unsigned long cr4;
71
        unsigned long temp;
72
        struct Xgt_desc_struct gdt_descr;
73
 
74
        spin_lock(&efi_rt_lock);
75
        local_irq_save(efi_rt_eflags);
76
 
77
        /*
78
         * If I don't have PSE, I should just duplicate two entries in page
79
         * directory. If I have PSE, I just need to duplicate one entry in
80
         * page directory.
81
         */
82
        cr4 = read_cr4();
83
 
84
        if (cr4 & X86_CR4_PSE) {
85
                efi_bak_pg_dir_pointer[0].pgd =
86
                    swapper_pg_dir[pgd_index(0)].pgd;
87
                swapper_pg_dir[0].pgd =
88
                    swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
89
        } else {
90
                efi_bak_pg_dir_pointer[0].pgd =
91
                    swapper_pg_dir[pgd_index(0)].pgd;
92
                efi_bak_pg_dir_pointer[1].pgd =
93
                    swapper_pg_dir[pgd_index(0x400000)].pgd;
94
                swapper_pg_dir[pgd_index(0)].pgd =
95
                    swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
96
                temp = PAGE_OFFSET + 0x400000;
97
                swapper_pg_dir[pgd_index(0x400000)].pgd =
98
                    swapper_pg_dir[pgd_index(temp)].pgd;
99
        }
100
 
101
        /*
102
         * After the lock is released, the original page table is restored.
103
         */
104
        local_flush_tlb();
105
 
106
        gdt_descr.address = __pa(get_cpu_gdt_table(0));
107
        gdt_descr.size = GDT_SIZE - 1;
108
        load_gdt(&gdt_descr);
109
}
110
 
111
static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
112
{
113
        unsigned long cr4;
114
        struct Xgt_desc_struct gdt_descr;
115
 
116
        gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
117
        gdt_descr.size = GDT_SIZE - 1;
118
        load_gdt(&gdt_descr);
119
 
120
        cr4 = read_cr4();
121
 
122
        if (cr4 & X86_CR4_PSE) {
123
                swapper_pg_dir[pgd_index(0)].pgd =
124
                    efi_bak_pg_dir_pointer[0].pgd;
125
        } else {
126
                swapper_pg_dir[pgd_index(0)].pgd =
127
                    efi_bak_pg_dir_pointer[0].pgd;
128
                swapper_pg_dir[pgd_index(0x400000)].pgd =
129
                    efi_bak_pg_dir_pointer[1].pgd;
130
        }
131
 
132
        /*
133
         * After the lock is released, the original page table is restored.
134
         */
135
        local_flush_tlb();
136
 
137
        local_irq_restore(efi_rt_eflags);
138
        spin_unlock(&efi_rt_lock);
139
}
140
 
141
static efi_status_t
142
phys_efi_set_virtual_address_map(unsigned long memory_map_size,
143
                                 unsigned long descriptor_size,
144
                                 u32 descriptor_version,
145
                                 efi_memory_desc_t *virtual_map)
146
{
147
        efi_status_t status;
148
 
149
        efi_call_phys_prelog();
150
        status = efi_call_phys(efi_phys.set_virtual_address_map,
151
                                     memory_map_size, descriptor_size,
152
                                     descriptor_version, virtual_map);
153
        efi_call_phys_epilog();
154
        return status;
155
}
156
 
157
static efi_status_t
158
phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
159
{
160
        efi_status_t status;
161
 
162
        efi_call_phys_prelog();
163
        status = efi_call_phys(efi_phys.get_time, tm, tc);
164
        efi_call_phys_epilog();
165
        return status;
166
}
167
 
168
inline int efi_set_rtc_mmss(unsigned long nowtime)
169
{
170
        int real_seconds, real_minutes;
171
        efi_status_t    status;
172
        efi_time_t      eft;
173
        efi_time_cap_t  cap;
174
 
175
        spin_lock(&efi_rt_lock);
176
        status = efi.get_time(&eft, &cap);
177
        spin_unlock(&efi_rt_lock);
178
        if (status != EFI_SUCCESS)
179
                panic("Ooops, efitime: can't read time!\n");
180
        real_seconds = nowtime % 60;
181
        real_minutes = nowtime / 60;
182
 
183
        if (((abs(real_minutes - eft.minute) + 15)/30) & 1)
184
                real_minutes += 30;
185
        real_minutes %= 60;
186
 
187
        eft.minute = real_minutes;
188
        eft.second = real_seconds;
189
 
190
        if (status != EFI_SUCCESS) {
191
                printk("Ooops: efitime: can't read time!\n");
192
                return -1;
193
        }
194
        return 0;
195
}
196
/*
197
 * This is used during kernel init before runtime
198
 * services have been remapped and also during suspend, therefore,
199
 * we'll need to call both in physical and virtual modes.
200
 */
201
inline unsigned long efi_get_time(void)
202
{
203
        efi_status_t status;
204
        efi_time_t eft;
205
        efi_time_cap_t cap;
206
 
207
        if (efi.get_time) {
208
                /* if we are in virtual mode use remapped function */
209
                status = efi.get_time(&eft, &cap);
210
        } else {
211
                /* we are in physical mode */
212
                status = phys_efi_get_time(&eft, &cap);
213
        }
214
 
215
        if (status != EFI_SUCCESS)
216
                printk("Oops: efitime: can't read time status: 0x%lx\n",status);
217
 
218
        return mktime(eft.year, eft.month, eft.day, eft.hour,
219
                        eft.minute, eft.second);
220
}
221
 
222
int is_available_memory(efi_memory_desc_t * md)
223
{
224
        if (!(md->attribute & EFI_MEMORY_WB))
225
                return 0;
226
 
227
        switch (md->type) {
228
                case EFI_LOADER_CODE:
229
                case EFI_LOADER_DATA:
230
                case EFI_BOOT_SERVICES_CODE:
231
                case EFI_BOOT_SERVICES_DATA:
232
                case EFI_CONVENTIONAL_MEMORY:
233
                        return 1;
234
        }
235
        return 0;
236
}
237
 
238
/*
239
 * We need to map the EFI memory map again after paging_init().
240
 */
241
void __init efi_map_memmap(void)
242
{
243
        memmap.map = NULL;
244
 
245
        memmap.map = bt_ioremap((unsigned long) memmap.phys_map,
246
                        (memmap.nr_map * memmap.desc_size));
247
        if (memmap.map == NULL)
248
                printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
249
 
250
        memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
251
}
252
 
253
#if EFI_DEBUG
254
static void __init print_efi_memmap(void)
255
{
256
        efi_memory_desc_t *md;
257
        void *p;
258
        int i;
259
 
260
        for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
261
                md = p;
262
                printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
263
                        "range=[0x%016llx-0x%016llx) (%lluMB)\n",
264
                        i, md->type, md->attribute, md->phys_addr,
265
                        md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
266
                        (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
267
        }
268
}
269
#endif  /*  EFI_DEBUG  */
270
 
271
/*
272
 * Walks the EFI memory map and calls CALLBACK once for each EFI
273
 * memory descriptor that has memory that is available for kernel use.
274
 */
275
void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
276
{
277
        int prev_valid = 0;
278
        struct range {
279
                unsigned long start;
280
                unsigned long end;
281
        } uninitialized_var(prev), curr;
282
        efi_memory_desc_t *md;
283
        unsigned long start, end;
284
        void *p;
285
 
286
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
287
                md = p;
288
 
289
                if ((md->num_pages == 0) || (!is_available_memory(md)))
290
                        continue;
291
 
292
                curr.start = md->phys_addr;
293
                curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
294
 
295
                if (!prev_valid) {
296
                        prev = curr;
297
                        prev_valid = 1;
298
                } else {
299
                        if (curr.start < prev.start)
300
                                printk(KERN_INFO PFX "Unordered memory map\n");
301
                        if (prev.end == curr.start)
302
                                prev.end = curr.end;
303
                        else {
304
                                start =
305
                                    (unsigned long) (PAGE_ALIGN(prev.start));
306
                                end = (unsigned long) (prev.end & PAGE_MASK);
307
                                if ((end > start)
308
                                    && (*callback) (start, end, arg) < 0)
309
                                        return;
310
                                prev = curr;
311
                        }
312
                }
313
        }
314
        if (prev_valid) {
315
                start = (unsigned long) PAGE_ALIGN(prev.start);
316
                end = (unsigned long) (prev.end & PAGE_MASK);
317
                if (end > start)
318
                        (*callback) (start, end, arg);
319
        }
320
}
321
 
322
void __init efi_init(void)
323
{
324
        efi_config_table_t *config_tables;
325
        efi_runtime_services_t *runtime;
326
        efi_char16_t *c16;
327
        char vendor[100] = "unknown";
328
        unsigned long num_config_tables;
329
        int i = 0;
330
 
331
        memset(&efi, 0, sizeof(efi) );
332
        memset(&efi_phys, 0, sizeof(efi_phys));
333
 
334
        efi_phys.systab =
335
                (efi_system_table_t *)boot_params.efi_info.efi_systab;
336
        memmap.phys_map = (void *)boot_params.efi_info.efi_memmap;
337
        memmap.nr_map = boot_params.efi_info.efi_memmap_size/
338
                boot_params.efi_info.efi_memdesc_size;
339
        memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
340
        memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
341
 
342
        efi.systab = (efi_system_table_t *)
343
                boot_ioremap((unsigned long) efi_phys.systab,
344
                        sizeof(efi_system_table_t));
345
        /*
346
         * Verify the EFI Table
347
         */
348
        if (efi.systab == NULL)
349
                printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
350
        if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
351
                printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
352
        if ((efi.systab->hdr.revision >> 16) == 0)
353
                printk(KERN_ERR PFX "Warning: EFI system table version "
354
                       "%d.%02d, expected 1.00 or greater\n",
355
                       efi.systab->hdr.revision >> 16,
356
                       efi.systab->hdr.revision & 0xffff);
357
 
358
        /*
359
         * Grab some details from the system table
360
         */
361
        num_config_tables = efi.systab->nr_tables;
362
        config_tables = (efi_config_table_t *)efi.systab->tables;
363
        runtime = efi.systab->runtime;
364
 
365
        /*
366
         * Show what we know for posterity
367
         */
368
        c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2);
369
        if (c16) {
370
                for (i = 0; i < (sizeof(vendor) - 1) && *c16; ++i)
371
                        vendor[i] = *c16++;
372
                vendor[i] = '\0';
373
        } else
374
                printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
375
 
376
        printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n",
377
               efi.systab->hdr.revision >> 16,
378
               efi.systab->hdr.revision & 0xffff, vendor);
379
 
380
        /*
381
         * Let's see what config tables the firmware passed to us.
382
         */
383
        config_tables = (efi_config_table_t *)
384
                                boot_ioremap((unsigned long) config_tables,
385
                                num_config_tables * sizeof(efi_config_table_t));
386
 
387
        if (config_tables == NULL)
388
                printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n");
389
 
390
        efi.mps        = EFI_INVALID_TABLE_ADDR;
391
        efi.acpi       = EFI_INVALID_TABLE_ADDR;
392
        efi.acpi20     = EFI_INVALID_TABLE_ADDR;
393
        efi.smbios     = EFI_INVALID_TABLE_ADDR;
394
        efi.sal_systab = EFI_INVALID_TABLE_ADDR;
395
        efi.boot_info  = EFI_INVALID_TABLE_ADDR;
396
        efi.hcdp       = EFI_INVALID_TABLE_ADDR;
397
        efi.uga        = EFI_INVALID_TABLE_ADDR;
398
 
399
        for (i = 0; i < num_config_tables; i++) {
400
                if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
401
                        efi.mps = config_tables[i].table;
402
                        printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table);
403
                } else
404
                    if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
405
                        efi.acpi20 = config_tables[i].table;
406
                        printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table);
407
                } else
408
                    if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
409
                        efi.acpi = config_tables[i].table;
410
                        printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table);
411
                } else
412
                    if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
413
                        efi.smbios = config_tables[i].table;
414
                        printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table);
415
                } else
416
                    if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
417
                        efi.hcdp = config_tables[i].table;
418
                        printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table);
419
                } else
420
                    if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) {
421
                        efi.uga = config_tables[i].table;
422
                        printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table);
423
                }
424
        }
425
        printk("\n");
426
 
427
        /*
428
         * Check out the runtime services table. We need to map
429
         * the runtime services table so that we can grab the physical
430
         * address of several of the EFI runtime functions, needed to
431
         * set the firmware into virtual mode.
432
         */
433
 
434
        runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long)
435
                                                runtime,
436
                                                sizeof(efi_runtime_services_t));
437
        if (runtime != NULL) {
438
                /*
439
                 * We will only need *early* access to the following
440
                 * two EFI runtime services before set_virtual_address_map
441
                 * is invoked.
442
                 */
443
                efi_phys.get_time = (efi_get_time_t *) runtime->get_time;
444
                efi_phys.set_virtual_address_map =
445
                        (efi_set_virtual_address_map_t *)
446
                                runtime->set_virtual_address_map;
447
        } else
448
                printk(KERN_ERR PFX "Could not map the runtime service table!\n");
449
 
450
        /* Map the EFI memory map for use until paging_init() */
451
        memmap.map = boot_ioremap(boot_params.efi_info.efi_memmap,
452
                                  boot_params.efi_info.efi_memmap_size);
453
        if (memmap.map == NULL)
454
                printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
455
 
456
        memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
457
 
458
#if EFI_DEBUG
459
        print_efi_memmap();
460
#endif
461
}
462
 
463
static inline void __init check_range_for_systab(efi_memory_desc_t *md)
464
{
465
        if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) &&
466
                ((unsigned long)efi_phys.systab < md->phys_addr +
467
                ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) {
468
                unsigned long addr;
469
 
470
                addr = md->virt_addr - md->phys_addr +
471
                        (unsigned long)efi_phys.systab;
472
                efi.systab = (efi_system_table_t *)addr;
473
        }
474
}
475
 
476
/*
477
 * Wrap all the virtual calls in a way that forces the parameters on the stack.
478
 */
479
 
480
#define efi_call_virt(f, args...) \
481
     ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args)
482
 
483
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
484
{
485
        return efi_call_virt(get_time, tm, tc);
486
}
487
 
488
static efi_status_t virt_efi_set_time (efi_time_t *tm)
489
{
490
        return efi_call_virt(set_time, tm);
491
}
492
 
493
static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled,
494
                                              efi_bool_t *pending,
495
                                              efi_time_t *tm)
496
{
497
        return efi_call_virt(get_wakeup_time, enabled, pending, tm);
498
}
499
 
500
static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled,
501
                                              efi_time_t *tm)
502
{
503
        return efi_call_virt(set_wakeup_time, enabled, tm);
504
}
505
 
506
static efi_status_t virt_efi_get_variable (efi_char16_t *name,
507
                                           efi_guid_t *vendor, u32 *attr,
508
                                           unsigned long *data_size, void *data)
509
{
510
        return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
511
}
512
 
513
static efi_status_t virt_efi_get_next_variable (unsigned long *name_size,
514
                                                efi_char16_t *name,
515
                                                efi_guid_t *vendor)
516
{
517
        return efi_call_virt(get_next_variable, name_size, name, vendor);
518
}
519
 
520
static efi_status_t virt_efi_set_variable (efi_char16_t *name,
521
                                           efi_guid_t *vendor,
522
                                           unsigned long attr,
523
                                           unsigned long data_size, void *data)
524
{
525
        return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
526
}
527
 
528
static efi_status_t virt_efi_get_next_high_mono_count (u32 *count)
529
{
530
        return efi_call_virt(get_next_high_mono_count, count);
531
}
532
 
533
static void virt_efi_reset_system (int reset_type, efi_status_t status,
534
                                   unsigned long data_size,
535
                                   efi_char16_t *data)
536
{
537
        efi_call_virt(reset_system, reset_type, status, data_size, data);
538
}
539
 
540
/*
541
 * This function will switch the EFI runtime services to virtual mode.
542
 * Essentially, look through the EFI memmap and map every region that
543
 * has the runtime attribute bit set in its memory descriptor and update
544
 * that memory descriptor with the virtual address obtained from ioremap().
545
 * This enables the runtime services to be called without having to
546
 * thunk back into physical mode for every invocation.
547
 */
548
 
549
void __init efi_enter_virtual_mode(void)
550
{
551
        efi_memory_desc_t *md;
552
        efi_status_t status;
553
        void *p;
554
 
555
        efi.systab = NULL;
556
 
557
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
558
                md = p;
559
 
560
                if (!(md->attribute & EFI_MEMORY_RUNTIME))
561
                        continue;
562
 
563
                md->virt_addr = (unsigned long)ioremap(md->phys_addr,
564
                        md->num_pages << EFI_PAGE_SHIFT);
565
                if (!(unsigned long)md->virt_addr) {
566
                        printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
567
                                (unsigned long)md->phys_addr);
568
                }
569
                /* update the virtual address of the EFI system table */
570
                check_range_for_systab(md);
571
        }
572
 
573
        BUG_ON(!efi.systab);
574
 
575
        status = phys_efi_set_virtual_address_map(
576
                        memmap.desc_size * memmap.nr_map,
577
                        memmap.desc_size,
578
                        memmap.desc_version,
579
                        memmap.phys_map);
580
 
581
        if (status != EFI_SUCCESS) {
582
                printk (KERN_ALERT "You are screwed! "
583
                        "Unable to switch EFI into virtual mode "
584
                        "(status=%lx)\n", status);
585
                panic("EFI call to SetVirtualAddressMap() failed!");
586
        }
587
 
588
        /*
589
         * Now that EFI is in virtual mode, update the function
590
         * pointers in the runtime service table to the new virtual addresses.
591
         */
592
 
593
        efi.get_time = virt_efi_get_time;
594
        efi.set_time = virt_efi_set_time;
595
        efi.get_wakeup_time = virt_efi_get_wakeup_time;
596
        efi.set_wakeup_time = virt_efi_set_wakeup_time;
597
        efi.get_variable = virt_efi_get_variable;
598
        efi.get_next_variable = virt_efi_get_next_variable;
599
        efi.set_variable = virt_efi_set_variable;
600
        efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
601
        efi.reset_system = virt_efi_reset_system;
602
}
603
 
604
void __init
605
efi_initialize_iomem_resources(struct resource *code_resource,
606
                               struct resource *data_resource,
607
                               struct resource *bss_resource)
608
{
609
        struct resource *res;
610
        efi_memory_desc_t *md;
611
        void *p;
612
 
613
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
614
                md = p;
615
 
616
                if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
617
                    0x100000000ULL)
618
                        continue;
619
                res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
620
                switch (md->type) {
621
                case EFI_RESERVED_TYPE:
622
                        res->name = "Reserved Memory";
623
                        break;
624
                case EFI_LOADER_CODE:
625
                        res->name = "Loader Code";
626
                        break;
627
                case EFI_LOADER_DATA:
628
                        res->name = "Loader Data";
629
                        break;
630
                case EFI_BOOT_SERVICES_DATA:
631
                        res->name = "BootServices Data";
632
                        break;
633
                case EFI_BOOT_SERVICES_CODE:
634
                        res->name = "BootServices Code";
635
                        break;
636
                case EFI_RUNTIME_SERVICES_CODE:
637
                        res->name = "Runtime Service Code";
638
                        break;
639
                case EFI_RUNTIME_SERVICES_DATA:
640
                        res->name = "Runtime Service Data";
641
                        break;
642
                case EFI_CONVENTIONAL_MEMORY:
643
                        res->name = "Conventional Memory";
644
                        break;
645
                case EFI_UNUSABLE_MEMORY:
646
                        res->name = "Unusable Memory";
647
                        break;
648
                case EFI_ACPI_RECLAIM_MEMORY:
649
                        res->name = "ACPI Reclaim";
650
                        break;
651
                case EFI_ACPI_MEMORY_NVS:
652
                        res->name = "ACPI NVS";
653
                        break;
654
                case EFI_MEMORY_MAPPED_IO:
655
                        res->name = "Memory Mapped IO";
656
                        break;
657
                case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
658
                        res->name = "Memory Mapped IO Port Space";
659
                        break;
660
                default:
661
                        res->name = "Reserved";
662
                        break;
663
                }
664
                res->start = md->phys_addr;
665
                res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1);
666
                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
667
                if (request_resource(&iomem_resource, res) < 0)
668
                        printk(KERN_ERR PFX "Failed to allocate res %s : "
669
                                "0x%llx-0x%llx\n", res->name,
670
                                (unsigned long long)res->start,
671
                                (unsigned long long)res->end);
672
                /*
673
                 * We don't know which region contains kernel data so we try
674
                 * it repeatedly and let the resource manager test it.
675
                 */
676
                if (md->type == EFI_CONVENTIONAL_MEMORY) {
677
                        request_resource(res, code_resource);
678
                        request_resource(res, data_resource);
679
                        request_resource(res, bss_resource);
680
#ifdef CONFIG_KEXEC
681
                        request_resource(res, &crashk_res);
682
#endif
683
                }
684
        }
685
}
686
 
687
/*
688
 * Convenience functions to obtain memory types and attributes
689
 */
690
 
691
u32 efi_mem_type(unsigned long phys_addr)
692
{
693
        efi_memory_desc_t *md;
694
        void *p;
695
 
696
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
697
                md = p;
698
                if ((md->phys_addr <= phys_addr) && (phys_addr <
699
                        (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
700
                        return md->type;
701
        }
702
        return 0;
703
}
704
 
705
u64 efi_mem_attributes(unsigned long phys_addr)
706
{
707
        efi_memory_desc_t *md;
708
        void *p;
709
 
710
        for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
711
                md = p;
712
                if ((md->phys_addr <= phys_addr) && (phys_addr <
713
                        (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
714
                        return md->attribute;
715
        }
716
        return 0;
717
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.