153 lines
2.9 KiB
C
153 lines
2.9 KiB
C
#include "config.h"
|
|
#include "libopenbios/bindings.h"
|
|
#include "libc/byteorder.h"
|
|
#include "libopenbios/ofmem.h"
|
|
#define NO_QEMU_PROTOS
|
|
#include "arch/common/fw_cfg.h"
|
|
|
|
#if !defined(CONFIG_SPARC64)
|
|
static volatile uint16_t *fw_cfg_cmd;
|
|
static volatile uint8_t *fw_cfg_data;
|
|
|
|
static void
|
|
fw_cfg_read_bytes(char *buf, unsigned int nbytes)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < nbytes; i++)
|
|
buf[i] = *fw_cfg_data;
|
|
}
|
|
|
|
void
|
|
fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
|
|
{
|
|
*fw_cfg_cmd = cmd;
|
|
fw_cfg_read_bytes(buf, nbytes);
|
|
}
|
|
#else
|
|
// XXX depends on PCI bus location, should be removed
|
|
static void
|
|
fw_cfg_read_bytes(char *buf, unsigned int nbytes)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < nbytes; i++)
|
|
buf[i] = inb(CONFIG_FW_CFG_ADDR + 1);
|
|
}
|
|
|
|
void
|
|
fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes)
|
|
{
|
|
outw(cmd, CONFIG_FW_CFG_ADDR);
|
|
fw_cfg_read_bytes(buf, nbytes);
|
|
}
|
|
#endif
|
|
|
|
uint64_t
|
|
fw_cfg_read_i64(uint16_t cmd)
|
|
{
|
|
uint64_t buf;
|
|
|
|
fw_cfg_read(cmd, (char *)&buf, sizeof(uint64_t));
|
|
|
|
return __le64_to_cpu(buf);
|
|
}
|
|
|
|
uint32_t
|
|
fw_cfg_read_i32(uint16_t cmd)
|
|
{
|
|
uint32_t buf;
|
|
|
|
fw_cfg_read(cmd, (char *)&buf, sizeof(uint32_t));
|
|
|
|
return __le32_to_cpu(buf);
|
|
}
|
|
|
|
uint16_t
|
|
fw_cfg_read_i16(uint16_t cmd)
|
|
{
|
|
uint16_t buf;
|
|
|
|
fw_cfg_read(cmd, (char *)&buf, sizeof(uint16_t));
|
|
|
|
return __le16_to_cpu(buf);
|
|
}
|
|
|
|
uint32_t
|
|
fw_cfg_find_file(const char *filename, uint16_t *select, uint32_t *size)
|
|
{
|
|
FWCfgFile f;
|
|
unsigned int i;
|
|
uint32_t buf, count;
|
|
|
|
/* Unusually all FW_CFG_FILE_DIR fields are BE */
|
|
fw_cfg_read(FW_CFG_FILE_DIR, (char *)&buf, sizeof(uint32_t));
|
|
count = __be32_to_cpu(buf);
|
|
|
|
for (i = 0; i < count; i++) {
|
|
fw_cfg_read_bytes((char *)&f, sizeof(f));
|
|
|
|
if (!strcmp(f.name, filename)) {
|
|
*select = __be16_to_cpu(f.select);
|
|
*size = __be32_to_cpu(f.size);
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
fw_cfg_read_file(const char *filename, uint32_t *size)
|
|
{
|
|
uint16_t cmd;
|
|
uint32_t nbytes;
|
|
char *buf;
|
|
|
|
if (fw_cfg_find_file(filename, &cmd, &nbytes)) {
|
|
buf = malloc(nbytes);
|
|
fw_cfg_read(cmd, buf, nbytes);
|
|
*size = nbytes;
|
|
return buf;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// ( fname fnamelen -- buf buflen -1 | 0 )
|
|
//
|
|
|
|
void
|
|
forth_fw_cfg_read_file(void)
|
|
{
|
|
char *filename = pop_fstr_copy();
|
|
char *buffer;
|
|
uint32_t size;
|
|
|
|
buffer = fw_cfg_read_file(filename, &size);
|
|
if (buffer) {
|
|
PUSH(pointer2cell(buffer));
|
|
PUSH(size);
|
|
PUSH(-1);
|
|
|
|
return;
|
|
}
|
|
|
|
PUSH(0);
|
|
}
|
|
|
|
void
|
|
fw_cfg_init(void)
|
|
{
|
|
#if defined(CONFIG_SPARC32)
|
|
fw_cfg_cmd = (void *)ofmem_map_io(CONFIG_FW_CFG_ADDR, 2);
|
|
fw_cfg_data = (uint8_t *)fw_cfg_cmd + 2;
|
|
#elif defined(CONFIG_SPARC64)
|
|
// Nothing for the port version
|
|
#elif defined(CONFIG_PPC)
|
|
fw_cfg_cmd = (void *)CONFIG_FW_CFG_ADDR;
|
|
fw_cfg_data = (void *)(CONFIG_FW_CFG_ADDR + 2);
|
|
#endif
|
|
}
|