SGI ARCS port.

* Makefile.util.def (libgrubmods.a): Add dvh.c.
	* conf/Makefile.common (CCASFLAGS_PLATFORM): Add -mips3 on all mips
	platforms.
	* configure.ac: New target mips-arc.
	* gentpl.py: Likewise.
	* grub-core/Makefile.am: Likewise.
	* grub-core/Makefile.core.def: Likewise.
	(xz_decompress): Remove -D GRUB_MACHINE_LINK_ADDR.
	(none_decompress): Likewise.
	(lsdev): New module.
	(datetime): Use lib/arc/datetime.c on ARC.
	(part_dvh): New module.
	* grub-core/commands/arc/lsdev.c: New file.
	* grub-core/disk/arc/arcdisk.c: Likewise.
	* grub-core/kern/mips/arc/init.c: Likewise.
	* grub-core/kern/mips/cache_flush.S: Don't flush non 4-byte
	aligned addresses.
	* grub-core/kern/mips/dl.c (grub_arch_dl_check_header): Fix bigendian
	support.
	(grub_arch_dl_relocate_symbols): Likewise.
	* grub-core/kern/mips/loongson/init.c (grub_get_rtc): Moved from here...
	* grub-core/kern/mips/init.c (grub_get_rtc): ... here.
	* grub-core/kern/mips/startup.S (grub_arch_cpuclock): Have on all
	platforms.
	* grub-core/lib/arc/datetime.c: New file.
	* grub-core/loader/mips/linux.c: Always include time.h. Don't include
	pci.h on non-loongson.
	(envp_off) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove.
	(grub_linux_boot): Set unused registers to 0.
	(grub_cmd_linux) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove envp.
	* grub-core/mmap/mips/loongson/uppermem.c: Moved from here ...
	* grub-core/mmap/mips/uppermem.c: ...here.
	* grub-core/partmap/dvh.c: New file.
	* grub-core/term/arc/console.c: Likewise.
	* grub-core/term/terminfo.c (ANSI_C0_STR): New const.
	(grub_terminfo_set_current): Add terminal "arc".
	(grub_terminfo_readkey): Support ARC sequences.
	* include/grub/arc/arc.h: New file.
	* include/grub/arc/console.h: Likewise.
	* include/grub/disk.h (grub_disk_dev_id): Add
	GRUB_DISK_DEVICE_ARCDISK_ID.
	* include/grub/mips/arc/kernel.h: New file.
	* include/grub/mips/arc/memory.h: Likewise.
	* include/grub/mips/arc/time.h: Likewise.
	* include/grub/mips/loongson/kernel.h (grub_halt): Moved from here ...
	* include/grub/mips/kernel.h (grub_halt): ... here.
	* include/grub/mips/loongson.h (GRUB_CPU_REGISTER_WRAP): Moved from
	here...
	* include/grub/mips/mips.h (GRUB_CPU_REGISTER_WRAP): ... here.
	(GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): Moved from here ...
	* include/grub/mips/mips.h (GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): .. here
	* include/grub/mips/loongson/kernel.h (grub_reboot): Removed redundant
	proto.
	* include/grub/mips/loongson/memory.h (GRUB_ARCH_LOWMEMVSTART): Moved
	from here ...
	* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMVSTART): ... here.
	(GRUB_ARCH_LOWMEMPSTART): Moved from here ...
	* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMPSTART): ... here.
	(GRUB_ARCH_LOWMEMMAXSIZE): Moved from here ...
	* include/grub/mips/memory.h (GRUB_ARCH_LOWMEMMAXSIZE): ... here.
	(GRUB_ARCH_HIGHMEMPSTART): Moved from here ...
	* include/grub/mips/memory.h (GRUB_ARCH_HIGHMEMPSTART): ... here.
	(grub_phys_addr_t): Moved from here ...
	* include/grub/mips/memory.h (grub_phys_addr_t): ... here.
	(grub_vtop): Moved from here ...
	* include/grub/mips/memory.h (grub_vtop): ... here.
	(grub_map_memory): Moved from here ...
	* include/grub/mips/memory.h (grub_map_memory): ... here.
	(grub_unmap_memory): Moved from here ...
	* include/grub/mips/memory.h (grub_unmap_memory): ... here.
	(grub_machine_mmap_iterate): Moved from here ...
	* include/grub/mips/memory.h (grub_machine_mmap_iterate): ... here.
	(grub_mmap_get_lower): Moved from here ...
	* include/grub/mips/memory.h (grub_mmap_get_lower): ... here.
	(grub_mmap_get_upper): Moved from here ...
	* include/grub/mips/memory.h (grub_mmap_get_upper): ... here.
	* include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from
	here ...
	* include/grub/mips/time.h (grub_arch_cpuclock): ... here.
	* include/grub/mips/loongson/time.h (grub_get_rtc): Moved from
	here ...
	* include/grub/mips/time.h (grub_get_rtc): ... here.
	* include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from
	here ...
	* include/grub/mips/time.h (grub_arch_cpuclock): ... here.
	* include/grub/mips/loongson/time.h (grub_cpu_idle): Moved from
	here ...
	* include/grub/mips/time.h (grub_cpu_idle): ... here.
	* include/grub/offsets.h (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): New
	definition.
	(GRUB_KERNEL_MIPS_ARC_LINK_ALIGN): Likewise.
	(GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE): Likewise.
	(GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE): Likewise.
	(GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE): Likewise.
	(GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise.
	(GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise.
	(GRUB_KERNEL_MIPS_ARC_MOD_ALIGN): Likewise.
	(GRUB_MACHINE_LINK_ADDR): Likewise.
	* include/grub/terminfo.h (GRUB_TERMINFO_READKEY_MAX_LEN): Increased
	to 6.
	* util/grub-install.in: Run dvhtool on ARC.
	* util/grub-mkimage.c (image_targets): Add mips-arc.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-17 09:17:38 +02:00
commit 400b93718f
39 changed files with 1736 additions and 115 deletions

View file

@ -0,0 +1,203 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009,2010 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/kernel.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/arc/console.h>
#include <grub/cpu/memory.h>
#include <grub/cpu/time.h>
#include <grub/memory.h>
#include <grub/term.h>
#include <grub/arc/arc.h>
#include <grub/offsets.h>
const char *type_names[] = {
#ifdef GRUB_CPU_WORDS_BIGENDIAN
NULL,
#endif
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm",
"serial", "net", "video", "par", "point", "key", "audio", "other",
"rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer",
"keyboard", "term", "other", "line", "network", NULL
};
static int
iterate_rec (const char *prefix, const struct grub_arc_component *parent,
int (*hook) (const char *name,
const struct grub_arc_component *comp),
int alt_names)
{
const struct grub_arc_component *comp;
FOR_ARC_CHILDREN(comp, parent)
{
char *name;
const char *cname = NULL;
if (comp->type < ARRAY_SIZE (type_names))
cname = type_names[comp->type];
if (!cname)
cname = "unknown";
if (alt_names)
name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key);
else
name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key);
if (!name)
return 1;
if (hook (name, comp))
{
grub_free (name);
return 1;
}
if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names))
{
grub_free (name);
return 1;
}
grub_free (name);
}
return 0;
}
int
grub_arc_iterate_devs (int (*hook) (const char *name,
const struct grub_arc_component *comp),
int alt_names)
{
return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names);
}
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
struct grub_arc_memory_descriptor *cur = NULL;
while (1)
{
grub_memory_type_t type;
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
if (!cur)
return GRUB_ERR_NONE;
switch (cur->type)
{
case GRUB_ARC_MEMORY_EXCEPTION_BLOCK:
case GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK:
case GRUB_ARC_MEMORY_FW_PERMANENT:
default:
type = GRUB_MEMORY_RESERVED;
break;
case GRUB_ARC_MEMORY_FW_TEMPORARY:
case GRUB_ARC_MEMORY_FREE:
case GRUB_ARC_MEMORY_LOADED:
case GRUB_ARC_MEMORY_FREE_CONTIGUOUS:
type = GRUB_MEMORY_AVAILABLE;
break;
case GRUB_ARC_MEMORY_BADRAM:
type = GRUB_MEMORY_BADRAM;
break;
}
if (hook (((grub_uint64_t) cur->start_page) << 12,
((grub_uint64_t) cur->num_pages) << 12, type))
return GRUB_ERR_NONE;
}
}
void
grub_machine_init (void)
{
struct grub_arc_memory_descriptor *cur = NULL;
grub_console_init_early ();
/* FIXME: measure this. */
grub_arch_cpuclock = 64000000;
grub_install_get_time_ms (grub_rtc_get_time_ms);
while (1)
{
grub_uint64_t start, end;
cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur);
if (!cur)
break;
if (cur->type != GRUB_ARC_MEMORY_FREE
&& cur->type != GRUB_ARC_MEMORY_LOADED
&& cur->type != GRUB_ARC_MEMORY_FREE_CONTIGUOUS)
continue;
start = ((grub_uint64_t) cur->start_page) << 12;
end = ((grub_uint64_t) cur->num_pages) << 12;
end += start;
if ((grub_uint64_t) end > (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff))
end = (GRUB_KERNEL_MIPS_ARC_LINK_ADDR & 0x1fffffff);
if (end > start)
grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000),
end - start);
}
grub_console_init_lately ();
grub_arcdisk_init ();
}
void
grub_machine_fini (void)
{
}
void
grub_halt (void)
{
GRUB_ARC_FIRMWARE_VECTOR->powerdown ();
grub_millisleep (1500);
grub_printf ("Shutdown failed\n");
grub_refresh ();
while (1);
}
void
grub_exit (void)
{
GRUB_ARC_FIRMWARE_VECTOR->exit ();
grub_millisleep (1500);
grub_printf ("Exit failed\n");
grub_refresh ();
while (1);
}
void
grub_reboot (void)
{
GRUB_ARC_FIRMWARE_VECTOR->restart ();
grub_millisleep (1500);
grub_printf ("Reboot failed\n");
grub_refresh ();
while (1);
}

View file

@ -9,15 +9,15 @@
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
addiu $t1, $t1, 0xffff
addiu $t1, $t1, -0x4
bne $t1, $zero, 1b
addiu $t0, $t0, 0x1
addiu $t0, $t0, 0x4
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
addiu $t1, $t1, 0xffff
addiu $t1, $t1, -0x4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x1
addiu $t0, $t0, 0x4
sync

View file

@ -34,7 +34,7 @@ grub_arch_dl_check_header (void *ehdr)
Elf_Ehdr *e = ehdr;
/* Check the magic numbers. */
#ifdef WORDS_BIGENDIAN
#ifdef GRUB_CPU_WORDS_BIGENDIAN
if (e->e_ident[EI_CLASS] != ELFCLASS32
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|| e->e_machine != EM_MIPS)
@ -144,14 +144,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
rel < max;
rel++)
{
Elf_Word *addr;
grub_uint8_t *addr;
Elf_Sym *sym;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
sym = (Elf_Sym *) ((char *) mod->symtab
+ entsize * ELF_R_SYM (rel->r_info));
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
@ -163,7 +163,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
grub_uint32_t value;
Elf_Rel *rel2;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
@ -175,13 +179,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset);
((char *) seg->addr + rel2->r_offset
#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ 2
#endif
);
break;
}
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
}
break;
case R_MIPS_LO16:
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
break;
case R_MIPS_32:
@ -208,6 +219,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
case R_MIPS_GOT16:
case R_MIPS_CALL16:
/* FIXME: reuse*/
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);

View file

@ -18,6 +18,24 @@
#include <grub/kernel.h>
#include <grub/env.h>
#include <grub/cpu/time.h>
#include <grub/cpu/mips.h>
/* 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 ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
void
grub_machine_set_prefix (void)

View file

@ -31,6 +31,7 @@
#include <grub/cs5536.h>
#include <grub/term.h>
#include <grub/machine/ec.h>
#include <grub/cpu/memory.h>
extern void grub_video_sm712_init (void);
extern void grub_video_sis315pro_init (void);
@ -44,22 +45,6 @@ extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void);
extern void grub_boot_init (void);
/* 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 ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_TIMER_COUNT : "=r" (low));
if (low < last)
high++;
last = low;
return (((grub_uint64_t) high) << 32) | low;
}
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
{

View file

@ -51,11 +51,11 @@ VARIABLE(grub_prefix)
*/
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
VARIABLE (grub_arch_cpuclock)
.long 0
#ifdef GRUB_MACHINE_MIPS_LOONGSON
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_cpuclock)
.long 0
VARIABLE (grub_arch_memsize)
.long 0
VARIABLE (grub_arch_highmemsize)