mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@689 f158a5a8-5612-0410-a976-696ce0be7e32
219 lines
5.7 KiB
C
219 lines
5.7 KiB
C
/* tag: openbios forth environment, executable code
|
|
*
|
|
* Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer
|
|
*
|
|
* See the file "COPYING" for further information about
|
|
* the copyright and warranty status of this work.
|
|
*/
|
|
|
|
#include "openbios/config.h"
|
|
#include "openbios/bindings.h"
|
|
#include "openbios/drivers.h"
|
|
#include "asm/types.h"
|
|
#include "dict.h"
|
|
#include "kernel/kernel.h"
|
|
#include "kernel/stack.h"
|
|
#include "openbios/nvram.h"
|
|
#include "../../drivers/timer.h" // XXX
|
|
#include "sys_info.h"
|
|
#include "openbios.h"
|
|
#include "boot.h"
|
|
#include "video_subr.h"
|
|
|
|
#define MEMORY_SIZE (128*1024) /* 16K ram for hosted system */
|
|
#define DICTIONARY_SIZE (256*1024) /* 256K for the dictionary */
|
|
|
|
static ucell *memory;
|
|
|
|
int qemu_machine_type;
|
|
|
|
struct hwdef {
|
|
uint64_t iommu_base, slavio_base;
|
|
uint64_t intctl_base, counter_base, nvram_base, ms_kb_base, serial_base;
|
|
unsigned long fd_offset, counter_offset, intr_offset;
|
|
unsigned long aux1_offset, aux2_offset;
|
|
uint64_t dma_base, esp_base, le_base;
|
|
uint64_t tcx_base;
|
|
int machine_id_low, machine_id_high;
|
|
};
|
|
|
|
static const struct hwdef hwdefs[] = {
|
|
/* SS-5 */
|
|
{
|
|
.iommu_base = 0x10000000,
|
|
.tcx_base = 0x50000000,
|
|
.slavio_base = 0x71000000,
|
|
.ms_kb_base = 0x71000000,
|
|
.serial_base = 0x71100000,
|
|
.nvram_base = 0x71200000,
|
|
.fd_offset = 0x00400000,
|
|
.counter_offset = 0x00d00000,
|
|
.intr_offset = 0x00e00000,
|
|
.aux1_offset = 0x00900000,
|
|
.aux2_offset = 0x00910000,
|
|
.dma_base = 0x78400000,
|
|
.esp_base = 0x78800000,
|
|
.le_base = 0x78c00000,
|
|
.machine_id_low = 32,
|
|
.machine_id_high = 63,
|
|
},
|
|
/* SS-10 */
|
|
{
|
|
.iommu_base = 0xfe0000000ULL,
|
|
.tcx_base = 0xe20000000ULL,
|
|
.slavio_base = 0xff1000000ULL,
|
|
.ms_kb_base = 0xff1000000ULL,
|
|
.serial_base = 0xff1100000ULL,
|
|
.nvram_base = 0xff1200000ULL,
|
|
.fd_offset = 0x00700000, // 0xff1700000ULL,
|
|
.counter_offset = 0x00300000, // 0xff1300000ULL,
|
|
.intr_offset = 0x00400000, // 0xff1400000ULL,
|
|
.aux1_offset = 0x00800000, // 0xff1800000ULL,
|
|
.aux2_offset = 0x00a01000, // 0xff1a01000ULL,
|
|
.dma_base = 0xef0400000ULL,
|
|
.esp_base = 0xef0800000ULL,
|
|
.le_base = 0xef0c00000ULL,
|
|
.machine_id_low = 64,
|
|
.machine_id_high = 65,
|
|
},
|
|
/* SS-600MP */
|
|
{
|
|
.iommu_base = 0xfe0000000ULL,
|
|
.tcx_base = 0xe20000000ULL,
|
|
.slavio_base = 0xff1000000ULL,
|
|
.ms_kb_base = 0xff1000000ULL,
|
|
.serial_base = 0xff1100000ULL,
|
|
.nvram_base = 0xff1200000ULL,
|
|
.fd_offset = -1,
|
|
.counter_offset = 0x00300000, // 0xff1300000ULL,
|
|
.intr_offset = 0x00400000, // 0xff1400000ULL,
|
|
.aux1_offset = 0x00800000, // 0xff1800000ULL,
|
|
.aux2_offset = 0x00a01000, // 0xff1a01000ULL, XXX should not exist
|
|
.dma_base = 0xef0081000ULL,
|
|
.esp_base = 0xef0080000ULL,
|
|
.le_base = 0xef0060000ULL,
|
|
.machine_id_low = 66,
|
|
.machine_id_high = 66,
|
|
},
|
|
};
|
|
|
|
static const struct hwdef *hwdef;
|
|
|
|
void setup_timers(void)
|
|
{
|
|
}
|
|
|
|
void udelay(unsigned int usecs)
|
|
{
|
|
}
|
|
|
|
void mdelay(unsigned int msecs)
|
|
{
|
|
}
|
|
|
|
static void init_memory(void)
|
|
{
|
|
memory = malloc(MEMORY_SIZE);
|
|
if (!memory)
|
|
printk("panic: not enough memory on host system.\n");
|
|
|
|
/* we push start and end of memory to the stack
|
|
* so that it can be used by the forth word QUIT
|
|
* to initialize the memory allocator
|
|
*/
|
|
|
|
PUSH((ucell)memory);
|
|
PUSH((ucell)memory + MEMORY_SIZE);
|
|
}
|
|
|
|
static void
|
|
arch_init( void )
|
|
{
|
|
modules_init();
|
|
ob_init_mmu();
|
|
ob_init_iommu(hwdef->iommu_base);
|
|
#ifdef CONFIG_DRIVER_OBIO
|
|
ob_obio_init(hwdef->slavio_base, hwdef->fd_offset,
|
|
hwdef->counter_offset, hwdef->intr_offset,
|
|
hwdef->aux1_offset, hwdef->aux2_offset);
|
|
nvconf_init();
|
|
#endif
|
|
#ifdef CONFIG_DRIVER_SBUS
|
|
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
|
|
init_video((unsigned long)vmem, 1024, 768, 8, 1024);
|
|
#endif
|
|
ob_sbus_init(hwdef->iommu_base + 0x1000ULL, qemu_machine_type);
|
|
#endif
|
|
device_end();
|
|
|
|
bind_func("platform-boot", boot );
|
|
}
|
|
|
|
int openbios(void)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) {
|
|
if (hwdefs[i].machine_id_low <= qemu_machine_type &&
|
|
hwdefs[i].machine_id_high >= qemu_machine_type) {
|
|
hwdef = &hwdefs[i];
|
|
break;
|
|
}
|
|
}
|
|
if (!hwdef)
|
|
for(;;); // Internal inconsistency, hang
|
|
|
|
#ifdef CONFIG_DRIVER_SBUS
|
|
init_mmu_swift();
|
|
#endif
|
|
#ifdef CONFIG_DEBUG_CONSOLE
|
|
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
|
|
uart_init(hwdef->serial_base | (CONFIG_SERIAL_PORT? 0ULL: 4ULL),
|
|
CONFIG_SERIAL_SPEED);
|
|
#endif
|
|
#ifdef CONFIG_DEBUG_CONSOLE_VIDEO
|
|
tcx_init(hwdef->tcx_base);
|
|
kbd_init(hwdef->ms_kb_base);
|
|
#endif
|
|
/* Clear the screen. */
|
|
cls();
|
|
#endif
|
|
|
|
collect_sys_info(&sys_info);
|
|
|
|
dict = malloc(DICTIONARY_SIZE);
|
|
load_dictionary((char *)sys_info.dict_start,
|
|
(unsigned long)sys_info.dict_end
|
|
- (unsigned long)sys_info.dict_start);
|
|
|
|
#ifdef CONFIG_DEBUG_BOOT
|
|
printk("forth started.\n");
|
|
printk("initializing memory...");
|
|
#endif
|
|
|
|
init_memory();
|
|
|
|
#ifdef CONFIG_DEBUG_BOOT
|
|
printk("done\n");
|
|
#endif
|
|
|
|
PUSH_xt( bind_noname_func(arch_init) );
|
|
fword("PREPOST-initializer");
|
|
|
|
PC = (ucell)findword("initialize-of");
|
|
|
|
if (!PC) {
|
|
printk("panic: no dictionary entry point.\n");
|
|
return -1;
|
|
}
|
|
#ifdef CONFIG_DEBUG_DICTIONARY
|
|
printk("done (%d bytes).\n", dicthead);
|
|
printk("Jumping to dictionary...\n");
|
|
#endif
|
|
|
|
enterforth((xt_t)PC);
|
|
|
|
free(dict);
|
|
return 0;
|
|
}
|