mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Clean up configuration device and NVRAM access, add UUID to Sparc32
git-svn-id: svn://coreboot.org/openbios/openbios-devel@318 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -32,6 +32,10 @@
|
|||||||
#define BIOS_CFG_CMD 0x510
|
#define BIOS_CFG_CMD 0x510
|
||||||
#define BIOS_CFG_DATA 0x511
|
#define BIOS_CFG_DATA 0x511
|
||||||
|
|
||||||
|
#define NVRAM_ADDR_LO 0x74
|
||||||
|
#define NVRAM_ADDR_HI 0x75
|
||||||
|
#define NVRAM_DATA 0x77
|
||||||
|
|
||||||
#define APB_SPECIAL_BASE 0x1fe00000000ULL
|
#define APB_SPECIAL_BASE 0x1fe00000000ULL
|
||||||
#define PCI_CONFIG (APB_SPECIAL_BASE + 0x1000000ULL)
|
#define PCI_CONFIG (APB_SPECIAL_BASE + 0x1000000ULL)
|
||||||
#define APB_MEM_BASE 0x1ff00000000ULL
|
#define APB_MEM_BASE 0x1ff00000000ULL
|
||||||
@@ -40,20 +44,21 @@ static unsigned char intdict[256 * 1024];
|
|||||||
|
|
||||||
// XXX
|
// XXX
|
||||||
#define NVRAM_SIZE 0x2000
|
#define NVRAM_SIZE 0x2000
|
||||||
#define NVRAM_IDPROM 0x1fd0
|
#define NVRAM_IDPROM 0x1fd8
|
||||||
|
#define NVRAM_IDPROM_SIZE 32
|
||||||
#define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg))
|
#define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg))
|
||||||
#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15)
|
#define NVRAM_OB_SIZE ((0x1fd0 - NVRAM_OB_START) & ~15)
|
||||||
|
|
||||||
static ohwcfg_v3_t nv_info;
|
static ohwcfg_v3_t nv_info;
|
||||||
|
|
||||||
#define OBIO_CMDLINE_MAX 256
|
#define OBIO_CMDLINE_MAX 256
|
||||||
static char obio_cmdline[OBIO_CMDLINE_MAX];
|
static char obio_cmdline[OBIO_CMDLINE_MAX];
|
||||||
|
|
||||||
static uint8_t idprom[32];
|
static uint8_t idprom[NVRAM_IDPROM_SIZE];
|
||||||
|
|
||||||
struct hwdef {
|
struct hwdef {
|
||||||
pci_arch_t pci;
|
pci_arch_t pci;
|
||||||
uint8_t machine_id_low, machine_id_high;
|
uint16_t machine_id_low, machine_id_high;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hwdef hwdefs[] = {
|
static const struct hwdef hwdefs[] = {
|
||||||
@@ -556,12 +561,80 @@ id_cpu(void)
|
|||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
outw(__cpu_to_le16(cmd), BIOS_CFG_CMD);
|
||||||
|
for (i = 0; i < nbytes; i++)
|
||||||
|
buf[i] = inb(BIOS_CFG_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
fw_cfg_read_i64(uint16_t cmd)
|
||||||
|
{
|
||||||
|
char buf[sizeof(uint64_t)];
|
||||||
|
|
||||||
|
fw_cfg_read(cmd, buf, sizeof(uint64_t));
|
||||||
|
|
||||||
|
return __le64_to_cpu(*(uint64_t *)buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t nvram_read_byte(uint16_t offset)
|
||||||
|
{
|
||||||
|
outb(offset & 0xff, NVRAM_ADDR_LO);
|
||||||
|
outb(offset >> 8, NVRAM_ADDR_HI);
|
||||||
|
return inb(NVRAM_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvram_read(uint16_t offset, char *buf, unsigned int nbytes)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nbytes; i++)
|
||||||
|
buf[i] = nvram_read_byte(offset + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvram_write_byte(uint16_t offset, uint8_t val)
|
||||||
|
{
|
||||||
|
outb(offset & 0xff, NVRAM_ADDR_LO);
|
||||||
|
outb(offset >> 8, NVRAM_ADDR_HI);
|
||||||
|
outb(val, NVRAM_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nvram_write(uint16_t offset, const char *buf, unsigned int nbytes)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nbytes; i++)
|
||||||
|
nvram_write_byte(offset + i, buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t qemu_uuid[16];
|
static uint8_t qemu_uuid[16];
|
||||||
|
|
||||||
void arch_nvram_get(char *data)
|
void arch_nvram_get(char *data)
|
||||||
{
|
{
|
||||||
unsigned short i;
|
|
||||||
unsigned char *nvptr = (unsigned char *)&nv_info;
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
const struct cpudef *cpu;
|
const struct cpudef *cpu;
|
||||||
const char *bootpath;
|
const char *bootpath;
|
||||||
@@ -569,27 +642,19 @@ void arch_nvram_get(char *data)
|
|||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
uint64_t ram_size;
|
uint64_t ram_size;
|
||||||
uint32_t clock_frequency;
|
uint32_t clock_frequency;
|
||||||
|
uint16_t machine_id;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(ohwcfg_v3_t); i++) {
|
nvram_read(0, (char *)&nv_info, sizeof(ohwcfg_v3_t));
|
||||||
outb(i & 0xff, 0x74);
|
|
||||||
outb(i >> 8, 0x75);
|
|
||||||
*nvptr++ = inb(0x77);
|
|
||||||
}
|
|
||||||
|
|
||||||
outw(__cpu_to_le16(FW_CFG_SIGNATURE), BIOS_CFG_CMD);
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
buf[i] = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
|
fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
|
||||||
buf[4] = '\0';
|
buf[4] = '\0';
|
||||||
|
|
||||||
printk("Configuration device id %s", buf);
|
printk("Configuration device id %s", buf);
|
||||||
|
|
||||||
outw(__cpu_to_le16(FW_CFG_ID), BIOS_CFG_CMD);
|
temp = fw_cfg_read_i32(FW_CFG_ID);
|
||||||
for (i = 0; i < 4; i++)
|
machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
|
||||||
buf[i] = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
temp = __le32_to_cpu(*(uint32_t *)buf);
|
printk(" version %d machine id %d\n", temp, machine_id);
|
||||||
printk(" version %d\n", temp);
|
|
||||||
|
|
||||||
kernel_image = nv_info.kernel_image;
|
kernel_image = nv_info.kernel_image;
|
||||||
kernel_size = nv_info.kernel_size;
|
kernel_size = nv_info.kernel_size;
|
||||||
@@ -606,17 +671,9 @@ void arch_nvram_get(char *data)
|
|||||||
if (size)
|
if (size)
|
||||||
printk("kernel cmdline %s\n", obio_cmdline);
|
printk("kernel cmdline %s\n", obio_cmdline);
|
||||||
|
|
||||||
for (i = 0; i < NVRAM_OB_SIZE; i++) {
|
nvram_read(NVRAM_OB_START, data, NVRAM_OB_SIZE);
|
||||||
outb((i + NVRAM_OB_START) & 0xff, 0x74);
|
|
||||||
outb((i + NVRAM_OB_START) >> 8, 0x75);
|
|
||||||
data[i] = inb(0x77);
|
|
||||||
}
|
|
||||||
|
|
||||||
outw(__cpu_to_le16(FW_CFG_NB_CPUS), BIOS_CFG_CMD);
|
temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
buf[i] = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
temp = __le32_to_cpu(*(uint32_t *)buf);
|
|
||||||
|
|
||||||
printk("CPUs: %x", temp);
|
printk("CPUs: %x", temp);
|
||||||
|
|
||||||
@@ -628,9 +685,7 @@ void arch_nvram_get(char *data)
|
|||||||
printk(" x %s\n", cpu->name);
|
printk(" x %s\n", cpu->name);
|
||||||
|
|
||||||
// Add /uuid
|
// Add /uuid
|
||||||
outw(__cpu_to_le16(FW_CFG_UUID), BIOS_CFG_CMD);
|
fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16);
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
qemu_uuid[i] = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
printk("UUID: " UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
|
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[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
|
||||||
@@ -648,11 +703,7 @@ void arch_nvram_get(char *data)
|
|||||||
fword("property");
|
fword("property");
|
||||||
|
|
||||||
// Add /idprom
|
// Add /idprom
|
||||||
for (i = 0; i < 32; i++) {
|
nvram_read(NVRAM_IDPROM, (char *)idprom, NVRAM_IDPROM_SIZE);
|
||||||
outb((i + 0x1fd8) & 0xff, 0x74);
|
|
||||||
outb((i + 0x1fd8) >> 8, 0x75);
|
|
||||||
idprom[i] = inb(0x77);
|
|
||||||
}
|
|
||||||
|
|
||||||
PUSH((long)&idprom);
|
PUSH((long)&idprom);
|
||||||
PUSH(32);
|
PUSH(32);
|
||||||
@@ -668,11 +719,7 @@ void arch_nvram_get(char *data)
|
|||||||
push_str("/memory");
|
push_str("/memory");
|
||||||
fword("find-device");
|
fword("find-device");
|
||||||
|
|
||||||
outw(__cpu_to_le16(FW_CFG_RAM_SIZE), BIOS_CFG_CMD);
|
ram_size = fw_cfg_read_i64(FW_CFG_RAM_SIZE);
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
buf[i] = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
ram_size = __le64_to_cpu(*(uint64_t *)buf);
|
|
||||||
|
|
||||||
// All memory: 0 to RAM_size
|
// All memory: 0 to RAM_size
|
||||||
PUSH(0);
|
PUSH(0);
|
||||||
@@ -811,13 +858,7 @@ void arch_nvram_get(char *data)
|
|||||||
|
|
||||||
void arch_nvram_put(char *data)
|
void arch_nvram_put(char *data)
|
||||||
{
|
{
|
||||||
unsigned short i;
|
nvram_write(0, data, NVRAM_OB_SIZE);
|
||||||
|
|
||||||
for (i = 0; i < NVRAM_OB_SIZE; i++) {
|
|
||||||
outb((i + NVRAM_OB_START) & 0xff, 0x74);
|
|
||||||
outb((i + NVRAM_OB_START) >> 8, 0x75);
|
|
||||||
outb(data[i], 0x77);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int arch_nvram_size(void)
|
int arch_nvram_size(void)
|
||||||
@@ -851,15 +892,14 @@ static void
|
|||||||
arch_init( void )
|
arch_init( void )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint8_t qemu_machine_type;
|
uint16_t machine_id;
|
||||||
const struct hwdef *hwdef;
|
const struct hwdef *hwdef = NULL;
|
||||||
|
|
||||||
outw(__cpu_to_le16(FW_CFG_MACHINE_ID), BIOS_CFG_CMD);
|
machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
|
||||||
qemu_machine_type = inb(BIOS_CFG_DATA);
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) {
|
for (i = 0; i < sizeof(hwdefs) / sizeof(struct hwdef); i++) {
|
||||||
if (hwdefs[i].machine_id_low <= qemu_machine_type &&
|
if (hwdefs[i].machine_id_low <= machine_id &&
|
||||||
hwdefs[i].machine_id_high >= qemu_machine_type) {
|
hwdefs[i].machine_id_high >= machine_id) {
|
||||||
hwdef = &hwdefs[i];
|
hwdef = &hwdefs[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#define NO_QEMU_PROTOS
|
#define NO_QEMU_PROTOS
|
||||||
#include "openbios/fw_cfg.h"
|
#include "openbios/fw_cfg.h"
|
||||||
|
|
||||||
|
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
||||||
|
|
||||||
#define PROMDEV_KBD 0 /* input from keyboard */
|
#define PROMDEV_KBD 0 /* input from keyboard */
|
||||||
#define PROMDEV_SCREEN 0 /* output to screen */
|
#define PROMDEV_SCREEN 0 /* output to screen */
|
||||||
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
#define PROMDEV_TTYA 1 /* in/out to ttya */
|
||||||
@@ -964,6 +966,41 @@ id_machine(uint16_t machine_id)
|
|||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static volatile uint16_t *fw_cfg_cmd;
|
||||||
|
static volatile uint8_t *fw_cfg_data;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t qemu_uuid[16];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ob_nvram_init(uint64_t base, uint64_t offset)
|
ob_nvram_init(uint64_t base, uint64_t offset)
|
||||||
{
|
{
|
||||||
@@ -975,8 +1012,6 @@ ob_nvram_init(uint64_t base, uint64_t offset)
|
|||||||
const struct cpudef *cpu;
|
const struct cpudef *cpu;
|
||||||
const struct machdef *mach;
|
const struct machdef *mach;
|
||||||
ohwcfg_v3_t *header;
|
ohwcfg_v3_t *header;
|
||||||
volatile uint8_t *fw_cfg_data;
|
|
||||||
volatile uint16_t *fw_cfg_cmd;
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
|
|
||||||
@@ -989,28 +1024,23 @@ ob_nvram_init(uint64_t base, uint64_t offset)
|
|||||||
push_str("address");
|
push_str("address");
|
||||||
fword("property");
|
fword("property");
|
||||||
|
|
||||||
|
push_str("mk48t08");
|
||||||
|
fword("model");
|
||||||
|
|
||||||
|
fword("finish-device");
|
||||||
|
|
||||||
fw_cfg_cmd = map_io(CFG_ADDR, CFG_SIZE);
|
fw_cfg_cmd = map_io(CFG_ADDR, CFG_SIZE);
|
||||||
fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2;
|
fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2;
|
||||||
|
|
||||||
*fw_cfg_cmd = FW_CFG_SIGNATURE;
|
fw_cfg_read(FW_CFG_SIGNATURE, buf, 4);
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
buf[i] = *fw_cfg_data;
|
|
||||||
buf[4] = '\0';
|
buf[4] = '\0';
|
||||||
|
|
||||||
printk("Configuration device id %s", buf);
|
printk("Configuration device id %s", buf);
|
||||||
|
|
||||||
*fw_cfg_cmd = FW_CFG_ID;
|
temp = fw_cfg_read_i32(FW_CFG_ID);
|
||||||
for (i = 0; i < 4; i++)
|
machine_id = fw_cfg_read_i16(FW_CFG_MACHINE_ID);
|
||||||
buf[i] = *fw_cfg_data;
|
|
||||||
|
|
||||||
temp = __le32_to_cpu(*(uint32_t *)buf);
|
printk(" version %d machine id %d\n", temp, machine_id);
|
||||||
printk(" version %d", temp);
|
|
||||||
|
|
||||||
*fw_cfg_cmd = FW_CFG_MACHINE_ID;
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
buf[i] = *fw_cfg_data;
|
|
||||||
|
|
||||||
machine_id = __le16_to_cpu(*(uint16_t *)buf);
|
|
||||||
printk(" machine id %d\n", machine_id);
|
|
||||||
|
|
||||||
memcpy(&nv_info, nvram, sizeof(nv_info));
|
memcpy(&nv_info, nvram, sizeof(nv_info));
|
||||||
kernel_image = nv_info.kernel_image;
|
kernel_image = nv_info.kernel_image;
|
||||||
@@ -1029,15 +1059,26 @@ ob_nvram_init(uint64_t base, uint64_t offset)
|
|||||||
header->crc = OHW_compute_crc(header, 0x00, 0xF8);
|
header->crc = OHW_compute_crc(header, 0x00, 0xF8);
|
||||||
|
|
||||||
boot_device = nv_info.boot_devices[0];
|
boot_device = nv_info.boot_devices[0];
|
||||||
*fw_cfg_cmd = FW_CFG_NOGRAPHIC;
|
fw_cfg_read(FW_CFG_NOGRAPHIC, &nographic, 1);
|
||||||
nographic = *fw_cfg_data;
|
graphic_depth = fw_cfg_read_i16(FW_CFG_SUN4M_DEPTH);
|
||||||
*fw_cfg_cmd = FW_CFG_SUN4M_DEPTH;
|
|
||||||
graphic_depth = *fw_cfg_data;
|
|
||||||
|
|
||||||
push_str("mk48t08");
|
// Add /uuid
|
||||||
fword("model");
|
fw_cfg_read(FW_CFG_UUID, (char *)qemu_uuid, 16);
|
||||||
|
|
||||||
fword("finish-device");
|
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]);
|
||||||
|
|
||||||
|
push_str("/");
|
||||||
|
fword("find-device");
|
||||||
|
|
||||||
|
PUSH((long)&qemu_uuid);
|
||||||
|
PUSH(16);
|
||||||
|
fword("encode-bytes");
|
||||||
|
push_str("uuid");
|
||||||
|
fword("property");
|
||||||
|
|
||||||
// Add /idprom
|
// Add /idprom
|
||||||
push_str("/");
|
push_str("/");
|
||||||
@@ -1070,11 +1111,7 @@ ob_nvram_init(uint64_t base, uint64_t offset)
|
|||||||
fword("property");
|
fword("property");
|
||||||
|
|
||||||
// Add cpus
|
// Add cpus
|
||||||
*fw_cfg_cmd = FW_CFG_NB_CPUS;
|
temp = fw_cfg_read_i32(FW_CFG_NB_CPUS);
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
buf[i] = *fw_cfg_data;
|
|
||||||
|
|
||||||
temp = __le32_to_cpu(*(uint32_t *)buf);
|
|
||||||
|
|
||||||
printk("CPUs: %x", temp);
|
printk("CPUs: %x", temp);
|
||||||
cpu = id_cpu();
|
cpu = id_cpu();
|
||||||
|
|||||||
Reference in New Issue
Block a user