1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/ieee1275/ieee1275.h>
#include <grub/types.h>
/* Sun specific ieee1275 interfaces used by GRUB. */
int
grub_ieee1275_claim_vaddr (grub_addr_t vaddr, grub_size_t size)
{
struct claim_vaddr_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t align;
grub_ieee1275_cell_t size;
grub_ieee1275_cell_t virt;
grub_ieee1275_cell_t catch_result;
}
args;
INIT_IEEE1275_COMMON (&args.common, "call-method", 5, 2);
args.method = (grub_ieee1275_cell_t) "claim";
args.ihandle = grub_ieee1275_mmu;
args.align = 0;
args.size = size;
args.virt = vaddr;
args.catch_result = (grub_ieee1275_cell_t) -1;
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
return args.catch_result;
}
int
grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size,
grub_uint32_t align)
{
grub_uint32_t memory_ihandle;
struct alloc_physmem_args
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t align;
grub_ieee1275_cell_t size;
grub_ieee1275_cell_t catch_result;
grub_ieee1275_cell_t phys_high;
grub_ieee1275_cell_t phys_low;
}
args;
grub_ssize_t actual = 0;
grub_ieee1275_get_property (grub_ieee1275_chosen, "memory",
&memory_ihandle, sizeof (memory_ihandle),
&actual);
if (actual != sizeof (memory_ihandle))
return -1;
if (!align)
align = 1;
INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 3);
args.method = (grub_ieee1275_cell_t) "claim";
args.ihandle = memory_ihandle;
args.align = (align ? align : 1);
args.size = size;
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
*paddr = args.phys_low;
return args.catch_result;
}
grub_uint64_t
grub_ieee1275_num_blocks (grub_ieee1275_ihandle_t ihandle)
{
struct nblocks_args_ieee1275
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t catch_result;
grub_ieee1275_cell_t blocks;
}
args;
INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
args.method = (grub_ieee1275_cell_t) "#blocks";
args.ihandle = ihandle;
args.catch_result = 1;
if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0))
return -1;
/*
* If the number of blocks exceeds the range of an unsigned number,
* return 0 to alert the caller to try the #blocks64 command.
*/
if (args.blocks >= 0xffffffffULL)
return 0;
return args.blocks;
}
grub_uint64_t
grub_ieee1275_num_blocks64 (grub_ieee1275_ihandle_t ihandle)
{
struct nblocks_args_ieee1275
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t catch_result;
grub_ieee1275_cell_t hi_blocks;
grub_ieee1275_cell_t lo_blocks;
}
args;
INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
args.method = (grub_ieee1275_cell_t) "#blocks64";
args.ihandle = ihandle;
args.catch_result = 1;
if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0))
return -1;
return ((args.hi_blocks << 32) | (args.lo_blocks));
}
|