Update OHW interface to version 3.

Use common ABI description file with Qemu for both Sparc32 and Sparc64.
Remove private definitions and magic constants.


git-svn-id: svn://coreboot.org/openbios/openbios-devel@176 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Blue Swirl
2007-11-14 19:25:43 +00:00
parent 65dca7dd37
commit a4340199fb
9 changed files with 316 additions and 112 deletions

View File

@@ -10,6 +10,8 @@
#include "psr.h"
#include "asi.h"
#include "asm/crs.h"
#define __ASSEMBLY__
#include "openbios/firmware_abi.h"
#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
@@ -17,8 +19,6 @@
#define PHYS_SS10_EEPROM 0xf1200000
#define PHYS_SS10_INTR0 0xf1400000
#define SUN_MACHINE_ID 0x1fd9
#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
.globl entry, _entry
@@ -56,12 +56,17 @@ entry:
! Ok, this is SS-5
mov 0x80, %y
! Find architecture specific part
set PHYS_JJ_EEPROM + OHW_ARCH_PTR, %g1
lduha [%g1] ASI_M_BYPASS, %g2
set PHYS_JJ_EEPROM, %g1
add %g1, %g2, %g3
! Check if this not the first SMP CPU, if so, bypass PROM entirely
set PHYS_JJ_EEPROM + 0x2E, %g1
add %g3, SPARC_SMP_VALID, %g1
lduba [%g1] ASI_M_BYPASS, %g2
stba %g0, [%g1] ASI_M_BYPASS
set PHYS_JJ_EEPROM + 0x30, %g1
lda [%g1] ASI_M_BYPASS, %g1
set PHYS_JJ_EEPROM + OHW_RAM_SIZE, %g1
ldda [%g1] ASI_M_BYPASS, %g0
tst %g2
bz first_cpu
nop
@@ -73,17 +78,17 @@ entry:
sta %g1, [%g2] ASI_M_BYPASS ! clear softints
add %g2, 4, %g2
sta %g0, [%g2] ASI_M_BYPASS ! clear softints
set PHYS_JJ_EEPROM + 0x3C, %g1
add %g3, SPARC_SMP_CTXTBL, %g1
lda [%g1] ASI_M_BYPASS, %g2
sta %g0, [%g1] ASI_M_BYPASS
set AC_M_CTPR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
set PHYS_JJ_EEPROM + 0x40, %g1
add %g3, SPARC_SMP_CTX, %g1
lda [%g1] ASI_M_BYPASS, %g2
sta %g0, [%g1] ASI_M_BYPASS
set AC_M_CXR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set context
set PHYS_JJ_EEPROM + 0x38, %g1
add %g3, SPARC_SMP_ENTRY, %g1
lda [%g1] ASI_M_BYPASS, %g2
sta %g0, [%g1] ASI_M_BYPASS
set 1, %g1
@@ -113,15 +118,20 @@ ss10:
bne bad_nvram
! Ok, this is SS-10 or SS-600MP
! Check if this not the first SMP CPU, if so, bypass PROM entirely
set PHYS_SS10_EEPROM + SUN_MACHINE_ID, %g1
set PHYS_SS10_EEPROM + SPARC_MACHINE_ID, %g1
lduba [%g1] ASI_M_CTL, %g2
mov %g2, %y
set PHYS_SS10_EEPROM + 0x2E, %g1
! Find architecture specific part
set PHYS_SS10_EEPROM + OHW_ARCH_PTR, %g1
lduha [%g1] ASI_M_CTL, %g2
set PHYS_SS10_EEPROM, %g1
add %g1, %g2, %g3
! Check if this not the first SMP CPU, if so, bypass PROM entirely
add %g3, SPARC_SMP_VALID, %g1
lduba [%g1] ASI_M_CTL, %g2
stba %g0, [%g2] ASI_M_CTL
set PHYS_SS10_EEPROM + 0x30, %g1
lda [%g1] ASI_M_CTL, %g1
set PHYS_SS10_EEPROM + OHW_RAM_SIZE, %g1
ldda [%g1] ASI_M_CTL, %g0
tst %g2
bz first_cpu
nop
@@ -132,17 +142,17 @@ ss10:
sta %g1, [%g2] ASI_M_CTL ! clear softints
add %g2, 4, %g2
sta %g0, [%g2] ASI_M_CTL ! clear softints
set PHYS_SS10_EEPROM + 0x3C, %g1
add %g3, SPARC_SMP_CTXTBL, %g1
lda [%g1] ASI_M_CTL, %g2
sta %g0, [%g1] ASI_M_CTL
set AC_M_CTPR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
set PHYS_JJ_EEPROM + 0x40, %g1
add %g3, SPARC_SMP_CTX, %g1
lda [%g1] ASI_M_CTL, %g2
sta %g0, [%g1] ASI_M_CTL
set AC_M_CXR, %g1
sta %g2, [%g1] ASI_M_MMUREGS ! set context
set PHYS_SS10_EEPROM + 0x38, %g1
add %g3, SPARC_SMP_ENTRY, %g1
lda [%g1] ASI_M_CTL, %g2
sta %g0, [%g1] ASI_M_CTL
set 1, %g1

View File

@@ -16,10 +16,10 @@ int linux_load(struct sys_info *, const char *filename, const char *cmdline);
void boot(void);
struct sys_info sys_info;
uint32_t kernel_image;
uint32_t kernel_size;
uint32_t cmdline;
uint32_t cmdline_size;
uint64_t kernel_image;
uint64_t kernel_size;
uint64_t cmdline;
uint64_t cmdline_size;
char boot_device;
void boot(void)

View File

@@ -12,3 +12,9 @@ int linux_load(struct sys_info *info, const char *file, const char *cmdline);
unsigned int start_elf(unsigned long entry_point, unsigned long param);
extern uint64_t kernel_image;
extern uint64_t kernel_size;
extern uint64_t cmdline;
extern uint64_t cmdline_size;
extern char boot_device;
extern struct sys_info sys_info;

View File

@@ -11,6 +11,8 @@
#include "asi.h"
#include "pstate.h"
#include "lsu.h"
#define __ASSEMBLY__
#include "openbios/firmware_abi.h"
#define PROM_ADDR 0x1fff0000000
@@ -49,7 +51,7 @@ entry:
! Get memory size from NVRAM
setx 0x1fe02000074, %g2, %g5
mov 0x30, %g2
mov OHW_RAM_SIZE, %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
add %g5, 1, %g1
stba %g0, [%g1] ASI_PHYS_BYPASS_EC_E
@@ -68,6 +70,30 @@ entry:
lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
or %g3, %g4, %g4
sll %g4, 8, %g4
inc %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
or %g3, %g4, %g4
sll %g4, 8, %g4
inc %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
or %g3, %g4, %g4
sll %g4, 8, %g4
inc %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
or %g3, %g4, %g4
sll %g4, 8, %g4
inc %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E
lduba [%g1] ASI_PHYS_BYPASS_EC_E, %g3
or %g3, %g4, %g4
sll %g4, 8, %g4
inc %g2
stba %g2, [%g5] ASI_PHYS_BYPASS_EC_E

View File

@@ -15,6 +15,8 @@
#include "openbios/stack.h"
#include "sys_info.h"
#include "openbios.h"
#include "openbios/firmware_abi.h"
#include "boot.h"
void boot(void);
@@ -23,35 +25,10 @@ static unsigned char intdict[256 * 1024];
// XXX
#define NVRAM_SIZE 0x2000
#define NVRAM_IDPROM 0x1fd0
#define NVRAM_OB_OFFSET 256
#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_OFFSET) & ~15)
#define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg))
#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15)
static struct qemu_nvram_v1 {
char id_string[16];
uint32_t version;
uint32_t nvram_size; // not used in Sun4m
char unused1[8];
char arch[12];
char curr_cpu;
char smp_cpus;
char unused2;
char nographic;
uint32_t ram_size;
char boot_device;
char unused3[3];
uint32_t kernel_image;
uint32_t kernel_size;
uint32_t cmdline;
uint32_t cmdline_size;
uint32_t initrd_image;
uint32_t initrd_size;
uint32_t nvram_image;
uint16_t width;
uint16_t height;
uint16_t depth;
char unused4[158];
uint16_t crc;
} nv_info;
ohwcfg_v3_t nv_info;
#define OBIO_CMDLINE_MAX 256
static char obio_cmdline[OBIO_CMDLINE_MAX];
@@ -148,38 +125,44 @@ void arch_nvram_get(char *data)
unsigned char *nvptr = &nv_info;
uint32_t size;
struct cpudef *cpu;
extern uint32_t kernel_image;
extern uint32_t kernel_size;
extern uint32_t cmdline;
extern uint32_t cmdline_size;
extern char boot_device;
for (i = 0; i < sizeof(struct qemu_nvram_v1); i++) {
for (i = 0; i < sizeof(ohwcfg_v3_t); i++) {
outb(i & 0xff, 0x74);
outb(i >> 8, 0x75);
*nvptr++ = inb(0x77);
}
printk("Nvram id %s, version %d\n", nv_info.struct_ident,
nv_info.struct_version);
if (strcmp(nv_info.struct_ident, "QEMU_BIOS") ||
nv_info.struct_version != 3 ||
OHW_compute_crc(&nv_info, 0x00, 0xF8) != nv_info.crc) {
printk("Unknown nvram, freezing!\n");
for (;;);
}
kernel_image = nv_info.kernel_image;
kernel_size = nv_info.kernel_size;
size = nv_info.cmdline_size;
if (size > OBIO_CMDLINE_MAX - 1)
size = OBIO_CMDLINE_MAX - 1;
memcpy(obio_cmdline, nv_info.cmdline, size);
memcpy(obio_cmdline, (void *)nv_info.cmdline, size);
obio_cmdline[size] = '\0';
cmdline = obio_cmdline;
cmdline_size = size;
boot_device = nv_info.boot_devices[0];
printk("kernel addr %x size %x\n", kernel_image, kernel_size);
if (size)
printk("kernel cmdline %s\n", obio_cmdline);
for (i = 0; i < NVRAM_OB_SIZE; i++) {
outb((i + NVRAM_OB_OFFSET) & 0xff, 0x74);
outb((i + NVRAM_OB_OFFSET) >> 8, 0x75);
outb((i + NVRAM_OB_START) & 0xff, 0x74);
outb((i + NVRAM_OB_START) >> 8, 0x75);
data[i] = inb(0x77);
}
printk("CPUs: %x", nv_info.smp_cpus);
printk("CPUs: %x", nv_info.nb_cpus);
cpu = id_cpu();
printk(" x %s\n", cpu->name);
}
@@ -189,8 +172,8 @@ void arch_nvram_put(char *data)
unsigned short i;
for (i = 0; i < NVRAM_OB_SIZE; i++) {
outb((i + NVRAM_OB_OFFSET) & 0xff, 0x74);
outb((i + NVRAM_OB_OFFSET) >> 8, 0x75);
outb((i + NVRAM_OB_START) & 0xff, 0x74);
outb((i + NVRAM_OB_START) >> 8, 0x75);
outb(data[i], 0x77);
}
}
@@ -250,8 +233,6 @@ arch_init( void )
int openbios(void)
{
extern struct sys_info sys_info;
#ifdef CONFIG_DEBUG_CONSOLE
#ifdef CONFIG_DEBUG_CONSOLE_SERIAL
uart_init(CONFIG_SERIAL_PORT, CONFIG_SERIAL_SPEED);

View File

@@ -11,8 +11,8 @@
#define debug(x...)
#endif
unsigned long qemu_mem_size;
unsigned long va_shift;
uint64_t qemu_mem_size;
uint64_t va_shift;
void collect_multiboot_info(struct sys_info *);

View File

@@ -19,6 +19,7 @@
#include "openbios/drivers.h"
#include "openbios/nvram.h"
#include "obio.h"
#include "openbios/firmware_abi.h"
#define REGISTER_NAMED_NODE( name, path ) do { \
bind_new_node( name##_flags_, name##_size_, \
@@ -289,26 +290,27 @@ ob_zs_init(uint64_t base, uint64_t offset, int intr, int slave, int keyboard)
}
static unsigned char *nvram;
struct qemu_nvram_v1 nv_info;
ohwcfg_v3_t nv_info;
#define NVRAM_OB_START (sizeof(ohwcfg_v3_t) + sizeof(struct sparc_arch_cfg))
#define NVRAM_OB_SIZE ((NVRAM_IDPROM - NVRAM_OB_START) & ~15)
void
arch_nvram_get(char *data)
{
memcpy(data, &nvram[sizeof(struct qemu_nvram_v1)],
NVRAM_IDPROM - sizeof(struct qemu_nvram_v1));
memcpy(data, &nvram[NVRAM_OB_START], NVRAM_OB_SIZE);
}
void
arch_nvram_put(char *data)
{
memcpy(&nvram[sizeof(struct qemu_nvram_v1)], data,
NVRAM_IDPROM - sizeof(struct qemu_nvram_v1));
memcpy(&nvram[NVRAM_OB_START], data, NVRAM_OB_SIZE);
}
int
arch_nvram_size(void)
{
return (NVRAM_IDPROM - sizeof(struct qemu_nvram_v1)) & ~15;
return NVRAM_OB_SIZE;
}
static void mb86904_init(void)
@@ -684,6 +686,7 @@ ob_nvram_init(uint64_t base, uint64_t offset)
uint32_t size;
unsigned int machine_id;
struct cpudef *cpu;
ohwcfg_v3_t *header;
ob_new_obio_device("eeprom", NULL);
@@ -696,9 +699,11 @@ ob_nvram_init(uint64_t base, uint64_t offset)
memcpy(&nv_info, nvram, sizeof(nv_info));
machine_id = (unsigned int)nvram[0x1fd9] & 0xff;
printk("Nvram id %s, version %d, machine id 0x%2.2x\n", nv_info.id_string,
nv_info.version, machine_id);
if (strcmp(nv_info.id_string, "QEMU_BIOS") || nv_info.version != 1) {
printk("Nvram id %s, version %d, machine id 0x%2.2x\n",
nv_info.struct_ident, nv_info.struct_version, machine_id);
if (strcmp(nv_info.struct_ident, "QEMU_BIOS") ||
nv_info.struct_version != 3 ||
OHW_compute_crc(&nv_info, 0x00, 0xF8) != nv_info.crc) {
printk("Unknown nvram, freezing!\n");
for (;;);
}
@@ -712,12 +717,13 @@ ob_nvram_init(uint64_t base, uint64_t offset)
obio_cmdline[size] = '\0';
cmdline = obio_cmdline;
cmdline_size = size;
((struct qemu_nvram_v1 *)nvram)->kernel_image = 0;
((struct qemu_nvram_v1 *)nvram)->kernel_size = 0;
((struct qemu_nvram_v1 *)nvram)->cmdline_size = 0;
header = (ohwcfg_v3_t *)nvram;
header->kernel_image = 0;
header->kernel_size = 0;
header->cmdline_size = 0;
boot_device = nv_info.boot_device;
nographic = nv_info.nographic;
boot_device = nv_info.boot_devices[0];
nographic = nv_info.graphic_flags & OHW_GF_NOGRAPHICS;
graphic_depth = nv_info.depth;
push_str("mk48t08");
@@ -779,10 +785,10 @@ ob_nvram_init(uint64_t base, uint64_t offset)
for (;;);
}
// Add cpus
printk("CPUs: %x", nv_info.smp_cpus);
printk("CPUs: %x", nv_info.nb_cpus);
cpu = id_cpu();
printk(" x %s\n", cpu->name);
for (i = 0; i < (unsigned int)nv_info.smp_cpus; i++) {
for (i = 0; i < (unsigned int)nv_info.nb_cpus; i++) {
push_str("/");
fword("find-device");
@@ -1091,13 +1097,17 @@ ob_interrupt_init(uint64_t base, unsigned long offset)
int
start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu)
{
ohwcfg_v3_t *header = (ohwcfg_v3_t *)nvram;
struct sparc_arch_cfg *sparc_header;
if (!cpu)
return -1;
*(uint32_t *)&nvram[0x38] = pc;
*(uint32_t *)&nvram[0x3c] = context_ptr;
*(uint32_t *)&nvram[0x40] = context;
nvram[0x2e] = cpu & 0xff;
sparc_header = &nvram[header->nvram_arch_ptr];
sparc_header->smp_entry = pc;
sparc_header->smp_ctxtbl = context_ptr;
sparc_header->smp_ctx = context;
sparc_header->valid = 1;
intregs->cpu_intregs[cpu].set = SUN4M_SOFT_INT(14);

View File

@@ -34,33 +34,6 @@
#define SLAVIO_SIZE 0x01000000
struct qemu_nvram_v1 {
char id_string[16];
uint32_t version;
uint32_t nvram_size; // not used in Sun4m
char unused1[8];
char arch[12];
char curr_cpu;
char smp_cpus;
char unused2;
char nographic;
uint32_t ram_size;
char boot_device;
char unused3[3];
uint32_t kernel_image;
uint32_t kernel_size;
uint32_t cmdline;
uint32_t cmdline_size;
uint32_t initrd_image;
uint32_t initrd_size;
uint32_t nvram_image;
uint16_t width;
uint16_t height;
uint16_t depth;
char unused4[158];
uint16_t crc;
};
#define SUN4M_NCPUS 16
#define PAGE_SIZE 4096

198
include/openbios/firmware_abi.h Executable file
View File

@@ -0,0 +1,198 @@
#ifndef FIRMWARE_ABI_H
#define FIRMWARE_ABI_H
#ifndef __ASSEMBLY__
/* Open Hack'Ware NVRAM configuration structure */
/* Version 3 */
typedef struct ohwcfg_v3_t ohwcfg_v3_t;
struct ohwcfg_v3_t {
/* 0x00: structure identifier */
uint8_t struct_ident[0x10];
/* 0x10: structure version and NVRAM description */
uint32_t struct_version;
uint16_t nvram_size;
uint16_t pad0;
uint16_t nvram_arch_ptr;
uint16_t nvram_arch_size;
uint16_t nvram_arch_crc;
uint8_t pad1[0x02];
/* 0x20: host architecture */
uint8_t arch[0x10];
/* 0x30: RAM/ROM description */
uint64_t RAM0_base;
uint64_t RAM0_size;
uint64_t RAM1_base;
uint64_t RAM1_size;
uint64_t RAM2_base;
uint64_t RAM2_size;
uint64_t RAM3_base;
uint64_t RAM3_size;
uint64_t ROM_base;
uint64_t ROM_size;
/* 0x80: Kernel description */
uint64_t kernel_image;
uint64_t kernel_size;
/* 0x90: Kernel command line */
uint64_t cmdline;
uint64_t cmdline_size;
/* 0xA0: Kernel boot image */
uint64_t initrd_image;
uint64_t initrd_size;
/* 0xB0: NVRAM image */
uint64_t NVRAM_image;
uint8_t pad2[8];
/* 0xC0: graphic configuration */
uint16_t width;
uint16_t height;
uint16_t depth;
uint16_t graphic_flags;
/* 0xC8: CPUs description */
uint8_t nb_cpus;
uint8_t boot_cpu;
uint8_t nboot_devices;
uint8_t pad3[5];
/* 0xD0: boot devices */
uint8_t boot_devices[0x10];
/* 0xE0 */
uint8_t pad4[0x1C]; /* 28 */
/* 0xFC: checksum */
uint16_t crc;
uint8_t pad5[0x02];
} __attribute__ (( packed ));
#define OHW_GF_NOGRAPHICS 0x0001
static inline uint16_t
OHW_crc_update (uint16_t prev, uint16_t value)
{
uint16_t tmp;
uint16_t pd, pd1, pd2;
tmp = prev >> 8;
pd = prev ^ value;
pd1 = pd & 0x000F;
pd2 = ((pd >> 4) & 0x000F) ^ pd1;
tmp ^= (pd1 << 3) | (pd1 << 8);
tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
return tmp;
}
static inline uint16_t
OHW_compute_crc (ohwcfg_v3_t *header, uint32_t start, uint32_t count)
{
uint32_t i;
uint16_t crc = 0xFFFF;
uint8_t *ptr = (uint8_t *)header;
int odd;
odd = count & 1;
count &= ~1;
for (i = 0; i != count; i++) {
crc = OHW_crc_update(crc, (ptr[start + i] << 8) | ptr[start + i + 1]);
}
if (odd) {
crc = OHW_crc_update(crc, ptr[start + i] << 8);
}
return crc;
}
/* Sparc32 runtime NVRAM structure for SMP CPU boot */
struct sparc_arch_cfg {
uint32_t smp_ctx;
uint32_t smp_ctxtbl;
uint32_t smp_entry;
uint8_t valid;
uint8_t unused[51];
};
/* OpenBIOS NVRAM partition */
struct OpenBIOS_nvpart_v1 {
uint8_t signature;
uint8_t checksum;
uint16_t len; // BE, length divided by 16
char name[12];
};
#define OPENBIOS_PART_SYSTEM 0x70
#define OPENBIOS_PART_FREE 0x7f
static inline void
OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size)
{
unsigned int i, sum;
uint8_t *tmpptr;
// Length divided by 16
header->len = cpu_to_be16(size >> 4);
// Checksum
tmpptr = (uint8_t *)header;
sum = *tmpptr;
for (i = 0; i < 14; i++) {
sum += tmpptr[2 + i];
sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
}
header->checksum = sum & 0xff;
}
static inline uint32_t
OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const unsigned char *str)
{
uint32_t len;
len = strlen(str) + 1;
memcpy(&nvram[addr], str, len);
return addr + len;
}
/* Sun IDPROM structure at the end of NVRAM */
struct Sun_nvram {
uint8_t type;
uint8_t machine_id;
uint8_t macaddr[6];
uint8_t unused[7];
uint8_t checksum;
};
static inline void
Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id)
{
uint8_t tmp, *tmpptr;
unsigned int i;
header->type = 1;
header->machine_id = machine_id & 0xff;
memcpy(&header->macaddr, macaddr, 6);
/* Calculate checksum */
tmp = 0;
tmpptr = (uint8_t *)header;
for (i = 0; i < 15; i++)
tmp ^= tmpptr[i];
header->checksum = tmp;
}
#else /* __ASSEMBLY__ */
/* Structure offsets for asm use */
/* Open Hack'Ware NVRAM configuration structure */
#define OHW_ARCH_PTR 0x18
#define OHW_RAM_SIZE 0x38
#define OHW_BOOT_CPU 0xC9
/* Sparc32 runtime NVRAM structure for SMP CPU boot */
#define SPARC_SMP_CTX 0x0
#define SPARC_SMP_CTXTBL 0x4
#define SPARC_SMP_ENTRY 0x8
#define SPARC_SMP_VALID 0xc
/* Sun IDPROM structure at the end of NVRAM */
#define SPARC_MACHINE_ID 0x1fd9
#endif /* __ASSEMBLY__ */
#endif /* FIRMWARE_ABI_H */