Files
openbios/arch/ppc/qemu/init.c

239 lines
5.1 KiB
C
Raw Normal View History

/*
* Creation Date: <2004/08/28 18:38:22 greg>
* Time-stamp: <2004/08/28 18:38:22 greg>
*
* <init.c>
*
* Initialization for qemu
*
* Copyright (C) 2004 Greg Watson
* Copyright (C) 2005 Stefan Reinauer
*
* based on mol/init.c:
*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Samuel & David Rydh
* (samuel@ibrium.se, dary@lindesign.se)
*
* This program 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
*
*/
#include "openbios/config.h"
#include "openbios/bindings.h"
#include "openbios/pci.h"
#include "openbios/nvram.h"
#include "qemu/qemu.h"
#include "ofmem.h"
#include "openbios-version.h"
#include "libc/byteorder.h"
#define NO_QEMU_PROTOS
#include "openbios/fw_cfg.h"
#define CFG_ADDR 0xf0000510
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
extern void unexpected_excep( int vector );
extern void ob_pci_init( void );
extern void setup_timers( void );
void
unexpected_excep( int vector )
{
printk("openbios panic: Unexpected exception %x\n", vector );
for( ;; )
;
}
enum {
ARCH_PREP = 0,
ARCH_MAC99,
ARCH_HEATHROW,
};
static const pci_arch_t known_arch[] = {
[ARCH_PREP] = { "PREP", 0x1057, 0x4801, 0x80800000, 0x800c0000,
0x80000000, 0x00100000, 0xf0000000, 0x10000000,
0x80000000, 0x00010000, 0x00000000, 0x00400000,
},
[ARCH_MAC99] = { "MAC99", 0x106b, 0x001F, 0xf2800000, 0xf2c00000,
0xf2000000, 0x02000000, 0x80000000, 0x10000000,
0xf2000000, 0x00800000, 0x00000000, 0x01000000,
},
[ARCH_HEATHROW] = { "HEATHROW", 0x1057, 0x0002, 0xfec00000, 0xfee00000,
0x80000000, 0x7f000000, 0x80000000, 0x01000000,
0xfe000000, 0x00800000, 0xfd000000, 0x01000000,
},
};
uint32_t isa_io_base;
static volatile uint16_t *fw_cfg_cmd = (void *)CFG_ADDR;
static volatile uint8_t *fw_cfg_data = (void *)(CFG_ADDR + 2);
static void
fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
{
unsigned int i;
*fw_cfg_cmd = cmd;
for (i = 0; i < nbytes; i++)
buf[i] = *fw_cfg_data;
}
static uint32_t
fw_cfg_read_i32(uint16_t cmd)
{
char buf[sizeof(uint32_t)];
fw_cfg_read(cmd, buf, sizeof(uint32_t));
return __le32_to_cpu(*(uint32_t *)buf);
}
static uint16_t
fw_cfg_read_i16(uint16_t cmd)
{
char buf[sizeof(uint16_t)];
fw_cfg_read(cmd, buf, sizeof(uint16_t));
return __le16_to_cpu(*(uint16_t *)buf);
}
void
entry( void )
{
uint32_t temp;
uint16_t machine_id;
char buf[5], qemu_uuid[16];
machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
arch = &known_arch[machine_id];
isa_io_base = arch->io_base;
serial_init();
printk("\n");
printk("=============================================================\n");
printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE );
fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
buf[4] = '\0';
printk("Configuration device id %s", buf);
temp = fw_cfg_read_i32(FW_CFG_ID);
printk(" version %d machine id %d\n", temp, machine_id);
temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
printk("CPUs: %x\n", temp);
fw_cfg_read(FW_CFG_UUID, qemu_uuid, 16);
printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
qemu_uuid[15]);
ofmem_init();
initialize_forth();
/* won't return */
printk("of_startup returned!\n");
for( ;; )
;
}
void
arch_of_init( void )
{
#ifdef USE_RTAS
phandle_t ph;
#endif
uint64_t ram_size;
devtree_init();
/* ISA BASE */
push_str("/");
fword("find-device");
PUSH(isa_io_base);
fword("encode-int");
push_str("isa-io-base");
fword("property");
/* memory info */
push_str("/memory");
fword("find-device");
/* all memory */
ram_size = get_ram_size();
PUSH(ram_size >> 32);
fword("encode-int");
PUSH(ram_size & 0xffffffff);
fword("encode-int");
fword("encode+");
PUSH(0);
fword("encode-int");
fword("encode+");
PUSH(0);
fword("encode-int");
fword("encode+");
push_str("reg");
fword("property");
/* available memory */
PUSH(0);
fword("encode-int");
PUSH((unsigned long)get_ram_bottom());
fword("encode-int");
fword("encode+");
PUSH((unsigned long)get_ram_top());
fword("encode-int");
fword("encode+");
PUSH(ram_size);
fword("encode-int");
fword("encode+");
push_str("available");
fword("property");
modules_init();
setup_timers();
#ifdef CONFIG_DRIVER_PCI
ob_pci_init();
#endif
node_methods_init();
#ifdef USE_RTAS
if( !(ph=find_dev("/rtas")) )
printk("Warning: No /rtas node\n");
else {
ulong size = 0x1000;
while( size < (ulong)of_rtas_end - (ulong)of_rtas_start )
size *= 2;
set_property( ph, "rtas-size", (char*)&size, sizeof(size) );
}
#endif
#if 0
if( getbool("tty-interface?") == 1 )
#endif
fword("activate-tty-interface");
device_end();
bind_func("platform-boot", boot );
}