Recommit my work on alpha

This commit is contained in:
Vladimir Serbinenko committed 2013-10-25 13:50:38 +02:00
1 parent c6dc6fa175
commit 85872c8373
31 files changed
+1401 -10

No files matched your search

+5
View File
@@ -140,6 +140,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
endif
if COND_alpha_srm
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/alpha/divide.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
endif
if COND_mips
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h
endif
+17
View File
@@ -70,6 +70,8 @@ kernel = {
ldadd = '$(LDADD_KERNEL)';
alpha_srm_cflags = '-mcpu=ev4 -mno-fp-regs -ffixed-8';
i386_coreboot_ldflags = '-Wl,-Ttext=0x8200';
i386_multiboot_ldflags = '-Wl,-Ttext=0x8200';
i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000';
@@ -78,6 +80,7 @@ kernel = {
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
alpha_srm_ldflags = '-Wl,-Ttext,0x20000000';
mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK';
@@ -97,6 +100,7 @@ kernel = {
mips_startup = kern/mips/startup.S;
sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
alpha_srm_startup = kern/alpha/srm/startup.S;
arm_uboot_startup = kern/arm/uboot/startup.S;
arm_efi_startup = kern/arm/efi/startup.S;
@@ -125,6 +129,7 @@ kernel = {
noemu_nodist = symlist.c;
mips = kern/generic/rtc_get_time_ms.c;
alpha_srm = kern/generic/rtc_get_time_ms.c;
ieee1275 = disk/ieee1275/ofdisk.c;
ieee1275 = kern/ieee1275/cmain.c;
@@ -237,6 +242,15 @@ kernel = {
arm = kern/arm/cache.c;
arm = kern/arm/misc.S;
alpha_srm = kern/alpha/srm/dispatch.S;
alpha_srm = kern/alpha/dl.c;
alpha_srm = kern/alpha/cache.S;
alpha_srm = kern/alpha/divide.S;
alpha_srm = kern/alpha/srm/pal_init.c;
alpha_srm = kern/alpha/srm/init.c;
alpha_srm = term/alpha/srm/console.c;
alpha_srm = disk/alpha/srm/srmdisk.c;
emu = disk/host.c;
emu = kern/emu/cache_s.S;
emu = kern/emu/hostdisk.c;
@@ -792,6 +806,8 @@ module = {
i386_qemu = lib/i386/halt.c;
efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c;
alpha_srm = lib/alpha/srm/halt.c;
emu = lib/emu/halt.c;
uboot = lib/uboot/halt.c;
};
@@ -1491,6 +1507,7 @@ module = {
powerpc_ieee1275 = lib/ieee1275/cmos.c;
mips_arc = lib/arc/datetime.c;
alpha_srm = lib/alpha/srm/datetime.c;
enable = noemu;
};
+237
View File
@@ -0,0 +1,237 @@
/* ofdisk.c - Open Firmware disk access. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2004,2006,2007,2008,2009,2011 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/misc.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/alpha/srm/srm.h>
static grub_srm_fileno_t last_handle = 0;
static char *last_path = NULL;
static int lnum = 0;
struct srmdisk_hash_ent
{
char *devpath;
int num;
struct srmdisk_hash_ent *next;
};
#define SRMDISK_HASH_SZ 8
static struct srmdisk_hash_ent *srmdisk_hash[SRMDISK_HASH_SZ];
static int
srmdisk_hash_fn (const char *devpath)
{
int hash = 0;
while (*devpath)
hash ^= *devpath++;
return (hash & (SRMDISK_HASH_SZ - 1));
}
static struct srmdisk_hash_ent *
srmdisk_hash_find (const char *devpath)
{
struct srmdisk_hash_ent *p = srmdisk_hash[srmdisk_hash_fn (devpath)];
while (p)
{
if (!grub_strcmp (p->devpath, devpath))
break;
p = p->next;
}
return p;
}
static struct srmdisk_hash_ent *
srmdisk_hash_add (char *devpath)
{
struct srmdisk_hash_ent *p;
struct srmdisk_hash_ent **head = &srmdisk_hash[srmdisk_hash_fn(devpath)];
p = grub_malloc (sizeof (*p));
if (!p)
return NULL;
p->devpath = devpath;
p->next = *head;
p->num = lnum++;
*head = p;
return p;
}
static int
grub_srmdisk_iterate (int (*hook) (const char *name))
{
(void) hook;
return 0;
}
static grub_err_t
reopen (const char *name)
{
grub_uint64_t r;
if (last_path && grub_strcmp (last_path, name) == 0)
{
grub_dprintf ("srmdisk", "using already opened %s\n", name);
return GRUB_ERR_NONE;
}
if (last_path)
{
grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_CLOSE, last_handle);
grub_free (last_path);
last_path = NULL;
last_handle = 0;
}
grub_dprintf ("srmdisk", "opening %s\n", name);
r = grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_OPEN, name, grub_strlen (name));
grub_printf ("<%lx>", r);
while (1);
if (r & (1ULL << 63))
{
grub_dprintf ("srmdisk", "couldn't open %s\n", name);
return grub_error (GRUB_ERR_IO, "couldn't open %s", name);
}
last_path = grub_strdup (name);
if (!last_path)
return grub_errno;
last_handle = r & 0xffffffff;
grub_dprintf ("srmdisk", "opened %s\n", name);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_srmdisk_open (const char *name, grub_disk_t disk)
{
char *fullname;
grub_err_t err;
struct srmdisk_hash_ent *hash;
if (grub_memcmp (name, "srm/", 4) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not srm device");
fullname = grub_strdup (name + 4);
if (!fullname)
return grub_errno;
disk->data = fullname;
grub_dprintf ("srmdisk", "opening %s\n", fullname);
hash = srmdisk_hash_find (fullname);
if (!hash)
hash = srmdisk_hash_add (fullname);
if (!hash)
return grub_errno;
err = reopen (fullname);
if (err)
return err;
{
grub_uint64_t res = 0;
int i;
/* FIXME: findout the block size. */
for (i = 31; i >= 0; i--)
{
char buf[512];
grub_dprintf ("srmdisk",
"seek to 0x%" PRIxGRUB_UINT64_T "\n",
res | (1UL << i));
if (grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_READ, last_handle, 512,
buf, res | (1ULL << i)) & (1ULL << 63))
continue;
res |= (1ULL << i);
}
grub_dprintf ("srmdisk",
"determined disk size 0x%" PRIxGRUB_UINT64_T "\n", res);
disk->total_sectors = res;
}
disk->id = hash->num;
return GRUB_ERR_NONE;
}
static void
grub_srmdisk_close (grub_disk_t disk)
{
grub_free (disk->data);
}
static grub_err_t
grub_srmdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
grub_err_t err;
err = reopen (disk->data);
if (err)
return err;
/* FIXME: handle incomplete read. */
if (grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_READ, last_handle,
size << 9,
buf, sector) & (1ULL << 63))
return grub_error (GRUB_ERR_READ_ERROR, "read failed");
return GRUB_ERR_NONE;
}
static grub_err_t
grub_srmdisk_write (grub_disk_t disk __attribute ((unused)),
grub_disk_addr_t sector __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return GRUB_ERR_NOT_IMPLEMENTED_YET;
}
static struct grub_disk_dev grub_srmdisk_dev =
{
.name = "srmdisk",
.id = GRUB_DISK_DEVICE_SRMDISK_ID,
.iterate = grub_srmdisk_iterate,
.open = grub_srmdisk_open,
.close = grub_srmdisk_close,
.read = grub_srmdisk_read,
.write = grub_srmdisk_write,
.next = 0
};
void
grub_srmdisk_init (void)
{
grub_disk_dev_register (&grub_srmdisk_dev);
}
void
grub_srmdisk_fini (void)
{
if (last_path)
{
grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_CLOSE, last_handle);
grub_free (last_path);
last_path = NULL;
last_handle = 0;
}
grub_disk_dev_unregister (&grub_srmdisk_dev);
}
+1
View File
@@ -0,0 +1 @@
SCSI 0 1004 0 2 200 0 0
+9
View File
@@ -0,0 +1,9 @@
#include <grub/symbol.h>
.set noreorder
.set nomacro
FUNCTION (grub_arch_sync_all_caches)
call_pal 134
ret $31,($26)
+114
View File
@@ -0,0 +1,114 @@
#include <grub/symbol.h>
.set noat
.macro PREAMBLE
subq $30, 31 * 8, $30
stq $0, (0 * 8)($30)
stq $1, (1 * 8)($30)
stq $2, (2 * 8)($30)
stq $3, (3 * 8)($30)
stq $4, (4 * 8)($30)
stq $5, (5 * 8)($30)
stq $6, (6 * 8)($30)
stq $7, (7 * 8)($30)
stq $8, (8 * 8)($30)
stq $9, (9 * 8)($30)
stq $10, (10 * 8)($30)
stq $11, (11 * 8)($30)
stq $12, (12 * 8)($30)
stq $13, (13 * 8)($30)
stq $14, (14 * 8)($30)
stq $15, (15 * 8)($30)
stq $16, (16 * 8)($30)
stq $17, (17 * 8)($30)
stq $18, (18 * 8)($30)
stq $19, (19 * 8)($30)
stq $20, (20 * 8)($30)
stq $21, (21 * 8)($30)
stq $22, (22 * 8)($30)
stq $23, (23 * 8)($30)
stq $24, (24 * 8)($30)
stq $25, (25 * 8)($30)
stq $26, (26 * 8)($30)
stq $28, (28 * 8)($30)
stq $29, (29 * 8)($30)
addq $30, (30 * 8), $18
/* load GP. */
br $27, 1f
1: ldgp $29, 0($27)
.endm
.macro POSTAMBLE
ldq $0, (0 * 8)($30)
ldq $1, (1 * 8)($30)
ldq $2, (2 * 8)($30)
ldq $3, (3 * 8)($30)
ldq $4, (4 * 8)($30)
ldq $5, (5 * 8)($30)
ldq $6, (6 * 8)($30)
ldq $7, (7 * 8)($30)
ldq $8, (8 * 8)($30)
ldq $9, (9 * 8)($30)
ldq $10, (10 * 8)($30)
ldq $11, (11 * 8)($30)
ldq $12, (12 * 8)($30)
ldq $13, (13 * 8)($30)
ldq $14, (14 * 8)($30)
ldq $15, (15 * 8)($30)
ldq $16, (16 * 8)($30)
ldq $17, (17 * 8)($30)
ldq $18, (18 * 8)($30)
ldq $19, (19 * 8)($30)
ldq $20, (20 * 8)($30)
ldq $21, (21 * 8)($30)
ldq $22, (22 * 8)($30)
ldq $23, (23 * 8)($30)
ldq $24, (24 * 8)($30)
ldq $25, (25 * 8)($30)
ldq $26, (26 * 8)($30)
ldq $28, (28 * 8)($30)
ldq $29, (29 * 8)($30)
addq $30, 31 * 8, $30
ret $31,($23)
.endm
FUNCTION (__divqu)
PREAMBLE
mov $24, $16
mov $25, $17
jsr $26, EXT_C (grub_divmod64)
mov $0, $27
POSTAMBLE
FUNCTION (__remqu)
PREAMBLE
mov $24, $16
mov $25, $17
jsr $26, EXT_C (grub_divmod64)
ldq $27, (30 * 8)($30)
POSTAMBLE
FUNCTION (__divlu)
PREAMBLE
sll $24, 32, $16
sra $16, 32, $16
sll $25, 32, $17
sra $17, 32, $17
mov $24, $16
mov $25, $17
jsr $26, EXT_C (grub_divmod64)
mov $0, $27
POSTAMBLE
FUNCTION (__remlu)
PREAMBLE
sll $24, 32, $16
sra $16, 32, $16
sll $25, 32, $17
sra $17, 32, $17
jsr $26, EXT_C (grub_divmod64)
ldq $27, (30 * 8)($30)
POSTAMBLE
+257
View File
@@ -0,0 +1,257 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/dl.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/cpu/types.h>
#include <grub/mm.h>
void
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
const Elf64_Ehdr *e = ehdr;
grub_size_t cntt = 0, cntg = 0;;
const Elf64_Shdr *s;
Elf64_Word entsize;
unsigned i;
/* Find a symbol table. */
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB)
break;
if (i == grub_le_to_cpu16 (e->e_shnum))
return;
entsize = s->sh_entsize;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize)))
if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA)
{
Elf64_Rela *rel, *max;
for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)),
max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize);
rel < max; rel++)
switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info)))
{
case R_ALPHA_LITERAL:
cntg++;
break;
default:;
}
}
*tramp = cntt;
*got = cntg;
}
/* Check if EHDR is a valid ELF header. */
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
if (e->e_ident[EI_CLASS] != ELFCLASS64
|| e->e_ident[EI_DATA] != ELFDATA2LSB
|| e->e_machine != EM_ALPHA)
return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
return GRUB_ERR_NONE;
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
Elf_Ehdr *e = ehdr;
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
grub_uint8_t *gp;
grub_uint64_t *gpptr;
gp = (grub_uint8_t *) mod->got;
gpptr = (grub_uint64_t *) mod->got;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
entsize = s->sh_entsize;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
if (s->sh_type == SHT_RELA)
{
grub_dl_segment_t seg;
/* Find the target segment. */
for (seg = mod->segment; seg; seg = seg->next)
if (seg->section == s->sh_info)
break;
if (seg)
{
Elf_Rela *rel, *max;
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
max = (Elf_Rela *) ((char *) rel + s->sh_size);
rel < max;
rel++)
{
grub_uint8_t *addr;
Elf_Sym *sym;
grub_uint64_t value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (grub_uint8_t *) seg->addr + rel->r_offset;
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
value = sym->st_value + rel->r_addend;
switch (ELF_R_TYPE (rel->r_info))
{
case R_ALPHA_REFQUAD:
*(grub_uint64_t *) addr += value;
break;
case R_ALPHA_REFLONG:
*(grub_uint32_t *) addr += value;
break;
case R_ALPHA_GPREL32:
*(grub_uint32_t *) addr += value - (grub_addr_t) gp;
break;
case R_ALPHA_GPDISP:
{
grub_int64_t off = gp - addr;
if (off < (-2147483647L - 1)
|| off > 2147483647L)
return grub_error (GRUB_ERR_BAD_MODULE,
"gpdisp offset too large");
/* Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
*(grub_uint16_t *) addr = (off + 0x8000) >> 16;
*(grub_uint16_t *) (addr + rel->r_addend) = off;
break;
}
case R_ALPHA_GPRELHIGH:
{
Elf_Rela *rel2;
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
value += (*(grub_uint16_t *) addr << 16);
value -= (grub_addr_t) gp;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_ALPHA_GPRELLOW)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset);
break;
}
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
if ((grub_int64_t) value < (-2147483647L - 1)
|| (grub_int64_t) value > 2147483647L)
return grub_error (GRUB_ERR_BAD_MODULE,
"gpdisp offset too large");
value += 0x8000;
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
break;
}
case R_ALPHA_GPRELLOW:
value -= (grub_addr_t) gp;
*(grub_uint16_t *) addr += value & 0xffff;
break;
case R_ALPHA_LITERAL:
*gpptr = value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr = ((grub_uint8_t *) gpptr - gp);
gpptr++;
break;
case R_ALPHA_SREL32:
*(grub_uint32_t *) addr += value - (grub_addr_t) seg->addr;
break;
case R_ALPHA_BRSGP:
value += (((*(grub_uint32_t *) addr)
& ((1 << 21) - 1)) << 2);
value -= (grub_addr_t) addr;
if (sym->st_other == STO_ALPHA_STD_GPLOAD)
value += 4;
else
value -= 4;
if (value & 3)
return grub_error (GRUB_ERR_BAD_MODULE,
"unaligned branch");
if ((value & ~((1UL << 22) - 1)) != 0
&& (value & ~((1UL << 22) - 1)) != ~((1UL << 22) - 1))
return grub_error (GRUB_ERR_BAD_MODULE,
"brs offset too large (%lx)",
value);
*(grub_uint32_t *) addr
= ((*(grub_uint32_t *) addr & ~((1 << 21) - 1))
| ((value >> 2) & ((1 << 21) - 1)));
break;
case R_ALPHA_LITUSE:
case R_ALPHA_HINT:
break;
default:
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unknown relocation type %d\n",
ELF_R_TYPE (rel->r_info));
}
break;
}
}
}
}
return GRUB_ERR_NONE;
}
+224
View File
@@ -0,0 +1,224 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/cache.h>
#include <grub/kernel.h>
#include <grub/memory.h>
#include <grub/env.h>
#include <grub/machine/srm.h>
#include <grub/machine/console.h>
/* FIXME: determine va_size. */
static void *kseg_addr = (void *) 0xfffffc0000000000;
static grub_uint64_t log_page_size;
extern char _start[];
extern char _end[];
grub_uint32_t grub_arch_pccclock;
/* FIXME: use interrupt to count high. */
grub_uint64_t
grub_get_rtc (void)
{
static grub_uint32_t high = 0;
static grub_uint32_t last = 0;
grub_uint32_t low;
asm volatile ("rpcc %0" : "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
static grub_addr_t
get_pfn (grub_addr_t va, grub_uint64_t ptbr)
{
grub_uint64_t *l1;
grub_uint64_t l1n;
grub_uint64_t *l2;
grub_uint64_t l2n;
grub_uint64_t *l3;
grub_uint64_t l3n;
l3n = va >> log_page_size;
l2n = l3n >> (log_page_size - 3);
l1n = l2n >> (log_page_size - 3);
l3n &= ((1 << (log_page_size - 3)) - 1);
l2n &= ((1 << (log_page_size - 3)) - 1);
l1n &= ((1 << (log_page_size - 3)) - 1);
l1 = ((grub_uint64_t *) kseg_addr + (ptbr << (log_page_size - 3))
+ l1n);
l2 = ((grub_uint64_t *) kseg_addr + ((*l1 >> 32) << (log_page_size - 3))
+ l2n);
l3 = ((grub_uint64_t *) kseg_addr + ((*l2 >> 32) << (log_page_size - 3))
+ l3n);
return (*l3 >> 32);
}
void pal_init(void);
void
grub_machine_init (void)
{
unsigned i;
struct grub_alpha_srm_memdesc *memdesc;
struct grub_alpha_srm_hwpcb *pcb;
grub_addr_t a;
grub_addr_t start, end;
grub_uint64_t low_pfn = ~0ULL, high_pfn = 0;
grub_arch_pccclock = GRUB_ALPHA_SRM_HWRPB.pcc_freq;
grub_console_init_early ();
pal_init ();
grub_install_get_time_ms (grub_rtc_get_time_ms);
for (log_page_size = 0;
!((1 << log_page_size) & GRUB_ALPHA_SRM_HWRPB.page_size);
log_page_size++);
memdesc = (struct grub_alpha_srm_memdesc *)
(GRUB_ALPHA_SRM_HWRPB_ADDR + GRUB_ALPHA_SRM_HWRPB.memory_descriptor_table);
pcb = (void *) (GRUB_ALPHA_SRM_HWRPB_ADDR
+ GRUB_ALPHA_SRM_HWRPB.cpu_slots_offset
+ (GRUB_ALPHA_SRM_HWRPB.primary_cpu_id
* GRUB_ALPHA_SRM_HWRPB.cpu_slot_size));
start = ALIGN_DOWN ((grub_addr_t) (&_start[0]),
GRUB_ALPHA_SRM_HWRPB.page_size);
end = ALIGN_UP (grub_modules_get_end (), GRUB_ALPHA_SRM_HWRPB.page_size);
for (a = start; a < end; a += GRUB_ALPHA_SRM_HWRPB.page_size)
{
grub_uint64_t curpfn = get_pfn (a, pcb->ptbr);
if (curpfn > high_pfn)
high_pfn = curpfn;
if (curpfn < low_pfn)
low_pfn = curpfn;
}
for (i = 0; i < memdesc->num_entries; i++)
{
grub_uint64_t from, to;
if (memdesc->entries[i].type
!= GRUB_ALPHA_SRM_MEMDESC_ENTRY_TYPE_AVAILABLE)
continue;
from = memdesc->entries[i].start_page;
to = memdesc->entries[i].start_page + memdesc->entries[i].num_pages;
if ((to > low_pfn) && (from < high_pfn + 1))
{
if (from < low_pfn)
/* from .. (lowpfn - 1) */
grub_mm_init_region ((char *) kseg_addr + (from << log_page_size),
(low_pfn - from) << log_page_size);
if (high_pfn + 1 < to)
/* (high_pfn + 1) .. (to - 1) */
grub_mm_init_region ((char *) kseg_addr
+ ((high_pfn + 1) << log_page_size),
(to - high_pfn - 1) << log_page_size);
}
else
/* from .. (to - 1) */
grub_mm_init_region ((char *) kseg_addr
+ (from << log_page_size),
(to - from) << log_page_size);
}
grub_console_init_lately ();
grub_srmdisk_init ();
char buf[512];
grub_alpha_srm_dispatch (0x22, 2, buf, sizeof (buf));
grub_printf ("Hello World %s\n", buf);
}
void
grub_machine_fini (void)
{
}
void
grub_machine_set_prefix (void)
{
grub_env_set ("prefix", grub_prefix);
}
void
grub_exit (void)
{
while (1);
}
void
grub_reboot (void)
{
while (1);
}
grub_addr_t
grub_arch_modules_addr (void)
{
return (grub_addr_t) _end;
}
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
struct grub_alpha_srm_memdesc *memdesc;
unsigned i;
memdesc = (struct grub_alpha_srm_memdesc *)
(GRUB_ALPHA_SRM_HWRPB_ADDR + GRUB_ALPHA_SRM_HWRPB.memory_descriptor_table);
for (i = 0; i < memdesc->num_entries; i++)
switch (memdesc->entries[i].type)
{
case GRUB_ALPHA_SRM_MEMDESC_ENTRY_TYPE_AVAILABLE:
hook (memdesc->entries[i].start_page << log_page_size,
memdesc->entries[i].num_pages << log_page_size,
GRUB_MEMORY_AVAILABLE);
break;
case GRUB_ALPHA_SRM_MEMDESC_ENTRY_TYPE_NONVOLATILE:
hook (memdesc->entries[i].start_page << log_page_size,
memdesc->entries[i].num_pages << log_page_size,
GRUB_MEMORY_NVRAM);
break;
case GRUB_ALPHA_SRM_MEMDESC_ENTRY_TYPE_RESERVED1:
case GRUB_ALPHA_SRM_MEMDESC_ENTRY_TYPE_RESERVED2:
default:
hook (memdesc->entries[i].start_page << log_page_size,
memdesc->entries[i].num_pages << log_page_size,
GRUB_MEMORY_RESERVED);
break;
}
return GRUB_ERR_NONE;
}
+54
View File
@@ -0,0 +1,54 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/offsets.h>
.set noreorder
.globl _start
.ent _start
_start:
.prologue 0
/* load GP. */
br $27, 1f
1: ldgp $29, 0($27)
/* Move modules out of the BSS. */
lda $1, __bss_start
lda $2, _end
lda $4, modsize
ldq $3, 0($4)
addq $3, 7, $3
sra $3, 3, $3
sll $3, 3, $4
subq $4, 8, $4
addq $1, $4, $1
addq $2, $4, $2
2:
beq $3, 3f
ldq $4, 0($1)
stq $4, 0($2)
subq $3, 1, $3
subq $1, 8, $1
subq $2, 8, $2
br 2b
3:
/* Clean BSS. */
lda $1, __bss_start
lda $2, _end
subq $2, $1, $2
sra $2, 3, $2
2:
beq $2, 3f
stq $31, 0($1)
subq $2, 1, $2
addq $1, 8, $1
br 2b
3:
/* call main. */
lda $27, EXT_C (grub_main)
jmp ($27)
.end _start
. = _start + GRUB_KERNEL_ALPHA_SRM_TOTAL_MODULE_SIZE
modsize:
.quad 0
+9 -5
View File
@@ -229,7 +229,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
unsigned i;
Elf_Shdr *s;
grub_size_t tsize = 0, talign = 1;
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__alpha__) || defined (__powerpc__)
grub_size_t tramp;
grub_size_t got;
#endif
@@ -244,7 +244,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
talign = s->sh_addralign;
}
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__alpha__) || defined (__powerpc__)
grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
tramp *= GRUB_ARCH_DL_TRAMP_SIZE;
got *= sizeof (grub_uint64_t);
@@ -313,7 +313,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
mod->segment = seg;
}
}
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__alpha__) || defined (__powerpc__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
ptr += tramp;
@@ -359,7 +359,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
str = (char *) e + s->sh_offset;
for (i = 0;
i < size / entsize;
i * entsize < size;
i++, sym = (Elf_Sym *) ((char *) sym + entsize))
{
unsigned char type = ELF_ST_TYPE (sym->st_info);
@@ -565,11 +565,15 @@ grub_dl_unref (grub_dl_t mod)
}
static void
grub_dl_flush_cache (grub_dl_t mod)
grub_dl_flush_cache (grub_dl_t mod __attribute__ ((unused)))
{
grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
(unsigned long) mod->sz, mod->base);
#ifdef __alpha__
grub_arch_sync_all_caches ();
#else
grub_arch_sync_caches (mod->base, mod->sz);
#endif
}
/* Load a module from core memory. */
+2
View File
@@ -554,6 +554,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
grub_uint64_t m = 0;
/* Skip the slow computation if 32-bit arithmetic is possible. */
#ifndef __alpha__
if (n < 0xffffffff && d < 0xffffffff)
{
if (r)
@@ -561,6 +562,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
return ((grub_uint32_t) n) / (grub_uint32_t) d;
}
#endif
while (bits--)
{
+37
View File
@@ -0,0 +1,37 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/datetime.h>
#include <grub/dl.h>
#include <grub/misc.h>
GRUB_MOD_LICENSE ("GPLv3+");
grub_err_t
grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"getting time isn't supported");
}
grub_err_t
grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"setting time isn't supported");
}
+25
View File
@@ -0,0 +1,25 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/misc.h>
void
grub_halt (void)
{
while (1);
}
+121
View File
@@ -0,0 +1,121 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 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/machine/srm.h>
#include <grub/machine/console.h>
#include <grub/term.h>
#include <grub/terminfo.h>
static int
readkey (struct grub_term_input *term __attribute__ ((unused)))
{
grub_uint64_t c;
c = grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_GETC, 0);
if (c & (1ULL << 63))
return -1;
return c & 0xffffffff;
}
#define NEWLINE " \r\n "
static void
put (struct grub_term_output *term __attribute__ ((unused)), const int c)
{
char chr = c;
if (c == '\n')
{
const char *str = NEWLINE, *ptr;
for (ptr = str; ptr < str + sizeof (NEWLINE) - 1; )
ptr += (grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_PUTS, 0, ptr,
str + sizeof (NEWLINE) - 1 - ptr)
& 0xff);
return;
}
grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_PUTS, 0, &chr, 1);
}
static struct grub_terminfo_output_state grub_console_terminfo_output;
static grub_err_t
grub_console_init_output (struct grub_term_output *term)
{
/* FIXME: get dimensions. */
grub_terminfo_output_init (term);
return 0;
}
static struct grub_terminfo_input_state grub_console_terminfo_input =
{
.readkey = readkey
};
static struct grub_terminfo_output_state grub_console_terminfo_output =
{
.put = put,
.width = 80,
.height = 25
};
static struct grub_term_input grub_console_term_input =
{
.name = "console",
.init = grub_terminfo_input_init,
.getkey = grub_terminfo_getkey,
.data = &grub_console_terminfo_input
};
static struct grub_term_output grub_console_term_output =
{
.name = "console",
.init = grub_console_init_output,
.putchar = grub_terminfo_putchar,
.getxy = grub_terminfo_getxy,
.getwh = grub_terminfo_getwh,
.gotoxy = grub_terminfo_gotoxy,
.cls = grub_terminfo_cls,
.setcolorstate = grub_terminfo_setcolorstate,
.setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
.data = &grub_console_terminfo_output,
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
};
void
grub_console_init_early (void)
{
grub_alpha_srm_dispatch (GRUB_ALPHA_SRM_OPEN_CONSOLE);
grub_term_register_input ("console", &grub_console_term_input);
grub_term_register_output ("console", &grub_console_term_output);
}
void grub_terminfo_init (void);
void
grub_console_init_lately (void)
{
grub_terminfo_init ();
/* FIXME */
grub_terminfo_output_register (&grub_console_term_output, "srm");
}
+13
View File
@@ -143,6 +143,19 @@ grub_terminfo_set_current (struct grub_term_output *term,
return grub_errno;
}
if (grub_strcmp ("srm", str) == 0)
{
data->name = grub_strdup ("srm");
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
data->cls = grub_strdup ("\e[2J");
data->reverse_video_on = grub_strdup ("\e[7m");
data->reverse_video_off = grub_strdup ("\e[0m");
data->cursor_on = grub_strdup ("\e[?25h");
data->cursor_off = grub_strdup ("\e[?25l");
data->setcolor = 0;
return grub_errno;
}
if (grub_strcmp ("ieee1275", str) == 0
|| grub_strcmp ("ieee1275-nocursor", str) == 0)
{