merge mainline and various cleanups

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-17 14:02:18 +02:00
commit 3666d5f636
380 changed files with 14873 additions and 1961 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

@ -8,3 +8,38 @@ FUNCTION (grub_cpu_flush_cache)
FUNCTION (grub_arch_sync_caches)
#include "cache_flush.S"
j $ra
FUNCTION (grub_arch_sync_dma_caches)
move $t2, $a0
addu $t3, $a0, $a1
srl $t2, $t2, 5
sll $t2, $t2, 5
addu $t3, $t3, 0x1f
srl $t3, $t3, 5
sll $t3, $t3, 5
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
addiu $t1, $t1, 0xffff
bne $t1, $zero, 1b
addiu $t0, $t0, 0x1
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
addiu $t1, $t1, 0xffff
bne $t1, $zero, 2b
addiu $t0, $t0, 0x1
sync
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 23, 0($t0)
addiu $t1, $t1, 0xffff
bne $t1, $zero, 2b
addiu $t0, $t0, 0x1
sync
jr $ra

View file

@ -12,16 +12,16 @@
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
#endif

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,11 +219,16 @@ 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);
gpptr++;
break;
case R_MIPS_JALR:
break;
default:
{
grub_free (gp);
@ -232,6 +248,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
void
grub_arch_dl_init_linker (void)
{
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0);
}

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,8 +31,10 @@
#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);
extern void grub_video_init (void);
extern void grub_bitmap_init (void);
extern void grub_font_init (void);
@ -41,22 +43,7 @@ extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
extern void grub_keylayouts_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;
}
extern void grub_boot_init (void);
grub_err_t
grub_machine_mmap_iterate (grub_memory_hook_t hook)
@ -78,7 +65,7 @@ init_pci (void)
/* FIXME: autoscan for BARs and devices. */
switch (pciid)
{
case GRUB_YEELOONG_OHCI_PCIID:
case GRUB_LOONGSON_OHCI_PCIID:
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0x5025000);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
@ -90,7 +77,7 @@ init_pci (void)
addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS);
grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES);
break;
case GRUB_YEELOONG_EHCI_PCIID:
case GRUB_LOONGSON_EHCI_PCIID:
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, 0x5026000);
addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
@ -162,7 +149,7 @@ grub_machine_init (void)
if (err)
grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg);
/* Yeeloong has only one memory slot. */
/* Yeeloong and Fuloong have only one memory slot. */
err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd);
if (err)
grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg);
@ -201,15 +188,19 @@ grub_machine_init (void)
relies on a working heap. */
grub_video_init ();
grub_video_sm712_init ();
grub_video_sis315pro_init ();
grub_bitmap_init ();
grub_font_init ();
grub_gfxterm_init ();
grub_keylayouts_init ();
grub_at_keyboard_init ();
if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG)
grub_at_keyboard_init ();
grub_terminfo_init ();
grub_serial_init ();
grub_boot_init ();
}
void
@ -220,10 +211,28 @@ grub_machine_fini (void)
void
grub_halt (void)
{
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_millisleep (1500);
switch (grub_arch_machine)
{
case GRUB_ARCH_MACHINE_FULOONG:
{
grub_pci_device_t dev;
grub_port_t p;
if (grub_cs5536_find (&dev))
{
p = (grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_GPIO_BAR)
& GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE;
grub_outl ((1 << 13), p + 4);
grub_outl ((1 << 29), p);
grub_millisleep (5000);
}
}
break;
case GRUB_ARCH_MACHINE_YEELOONG:
grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG)
& ~GRUB_CPU_YEELOONG_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG);
grub_millisleep (1500);
break;
}
grub_printf ("Shutdown failed\n");
grub_refresh ();

View file

@ -7,23 +7,30 @@
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/machine/memory.h>
#include <grub/cpu/memory.h>
#include <grub/memory.h>
#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
grub_uint32_t
grub_get_rtc (void)
{
static int calln = 0;
return calln++;
}
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
void
grub_machine_init (void)
{
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
grub_addr_t modend;
/* FIXME: measure this. */
grub_arch_cpuclock = 64000000;
modend = grub_modules_get_end ();
grub_mm_init_region ((void *) modend, RAMSIZE
- (modend - GRUB_ARCH_LOWMEMVSTART));
grub_install_get_time_ms (grub_rtc_get_time_ms);
grub_terminfo_init ();
grub_serial_init ();
}
void

View file

@ -20,6 +20,7 @@
#include <grub/symbol.h>
#include <grub/offsets.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>
#include <grub/offsets.h>
#define BASE_ADDR 8
@ -35,7 +36,7 @@ start:
bal cont
nop
. = _start + GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
total_module_size:
.long 0
@ -50,27 +51,30 @@ VARIABLE(grub_prefix)
*/
. = _start + GRUB_KERNEL_MACHINE_PREFIX_END
#ifdef GRUB_MACHINE_MIPS_YEELOONG
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_cpuclock)
.long 0
#ifdef GRUB_MACHINE_MIPS_LOONGSON
VARIABLE (grub_arch_busclock)
.long 0
VARIABLE (grub_arch_memsize)
.long 0
VARIABLE (grub_arch_highmemsize)
.long 0
VARIABLE (grub_arch_machine)
.long GRUB_ARCH_MACHINE_FULOONG
#endif
cont:
/* Save our base. */
move $s0, $ra
#ifdef GRUB_MACHINE_MIPS_YEELOONG
#ifdef GRUB_MACHINE_MIPS_LOONGSON
lui $t1, %hi(grub_arch_busclock)
addiu $t1, %lo(grub_arch_busclock)
sw $s2, 0($t1)
sw $s3, 4($t1)
sw $s4, 8($t1)
sw $s5, 12($t1)
sw $s7, 16($t1)
#endif
/* Move the modules out of BSS. */