mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
drivers part from openbios.patch-15-svn25.bz2
git-svn-id: svn://coreboot.org/openbios/openbios-devel@26 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -25,8 +25,9 @@
|
||||
#include "asm/dma.h"
|
||||
#include "esp.h"
|
||||
|
||||
#define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */
|
||||
#define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */
|
||||
#define MACIO_ESPDMA 0x08400000 /* ESP DMA controller */
|
||||
#define MACIO_ESP 0x08800000 /* ESP SCSI */
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
#define REGISTER_NAMED_NODE( name, path ) do { \
|
||||
@@ -294,16 +295,14 @@ NODE_METHODS(ob_sd) = {
|
||||
|
||||
|
||||
static int
|
||||
espdma_init(struct esp_dma *espdma)
|
||||
espdma_init(unsigned long base, struct esp_dma *espdma)
|
||||
{
|
||||
void *p;
|
||||
espdma->regs = (void *)map_io(base + MACIO_ESPDMA, 0x10);
|
||||
|
||||
/* Hardcode everything for MrCoffee. */
|
||||
if ((p = (void *)map_io(PHYS_JJ_ESPDMA, 0x10)) == 0) {
|
||||
if (espdma->regs == 0) {
|
||||
DPRINTF("espdma_init: cannot map registers\n");
|
||||
return -1;
|
||||
}
|
||||
espdma->regs = p;
|
||||
|
||||
DPRINTF("dma1: ");
|
||||
|
||||
@@ -340,6 +339,21 @@ espdma_init(struct esp_dma *espdma)
|
||||
}
|
||||
DPRINTF("\n");
|
||||
|
||||
push_str("/iommu/sbus/espdma");
|
||||
fword("find-device");
|
||||
|
||||
/* set reg */
|
||||
PUSH(4);
|
||||
fword("encode-int");
|
||||
PUSH(MACIO_ESPDMA);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0x00000010);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -358,7 +372,7 @@ ob_esp_initialize(__attribute__((unused)) esp_private_t **esp)
|
||||
/* set reg */
|
||||
PUSH(4);
|
||||
fword("encode-int");
|
||||
PUSH(0x08800000);
|
||||
PUSH(MACIO_ESP);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0x00000010);
|
||||
@@ -407,7 +421,8 @@ add_alias(const char *device, const char *alias)
|
||||
fword("property");
|
||||
}
|
||||
|
||||
int ob_esp_init(void)
|
||||
int
|
||||
ob_esp_init(unsigned long base)
|
||||
{
|
||||
int id, diskcount = 0, cdcount = 0, *counter_ptr;
|
||||
char nodebuff[256], aliasbuff[256];
|
||||
@@ -423,11 +438,11 @@ int ob_esp_init(void)
|
||||
|
||||
global_esp = esp;
|
||||
|
||||
if (espdma_init(&esp->espdma) != 0) {
|
||||
if (espdma_init(base, &esp->espdma) != 0) {
|
||||
return -1;
|
||||
}
|
||||
/* Get the IO region */
|
||||
esp->ll = (void *)map_io(PHYS_JJ_ESP, sizeof(struct esp_regs));
|
||||
esp->ll = (void *)map_io(base + MACIO_ESP, sizeof(struct esp_regs));
|
||||
if (esp->ll == 0) {
|
||||
DPRINTF("Can't map ESP registers\n");
|
||||
return -1;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "pgtsrmmu.h"
|
||||
#include "iommu.h"
|
||||
|
||||
#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */
|
||||
#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
|
||||
#define MKIOPTE(phys) (((((phys)>>4) & IOPTE_PAGE) | IOPERM) & ~IOPTE_WAZ)
|
||||
#define LOWMEMSZ 32 * 1024 * 1024
|
||||
@@ -61,7 +60,8 @@ struct iommu ciommu;
|
||||
|
||||
#define NCTX_SWIFT 0x100
|
||||
|
||||
static void iommu_init(struct iommu *t);
|
||||
static void iommu_init(struct iommu *t, unsigned long base);
|
||||
|
||||
static void
|
||||
iommu_invalidate(struct iommu_regs *regs) {
|
||||
regs->tlbflush = 0;
|
||||
@@ -199,11 +199,72 @@ map_io(unsigned pa, int size)
|
||||
* Switch page tables.
|
||||
*/
|
||||
void
|
||||
init_mmu_swift(void)
|
||||
init_mmu_swift(unsigned long base)
|
||||
{
|
||||
extern unsigned int qemu_mem_size;
|
||||
unsigned int addr, i;
|
||||
unsigned long pa, va;
|
||||
|
||||
push_str("/memory");
|
||||
fword("find-device");
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(qemu_mem_size);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(va2pa((unsigned long)&_data) - 1);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("available");
|
||||
fword("property");
|
||||
|
||||
push_str("/virtual-memory");
|
||||
fword("find-device");
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(base);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0x300);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(va2pa((unsigned long)&_start) - 1);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(va2pa((unsigned long)&_iomem));
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(-va2pa((unsigned long)&_iomem));
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("available");
|
||||
fword("property");
|
||||
|
||||
mem_init(&cio, (char *)&_end, (char *)&_iomem);
|
||||
|
||||
context_table = mem_zalloc(&cmem, NCTX_SWIFT * sizeof(int), NCTX_SWIFT * sizeof(int));
|
||||
@@ -249,7 +310,7 @@ init_mmu_swift(void)
|
||||
srmmu_set_context(0);
|
||||
srmmu_set_ctable_ptr(va2pa((unsigned long)context_table));
|
||||
srmmu_flush_whole_tlb();
|
||||
iommu_init(&ciommu);
|
||||
iommu_init(&ciommu, base);
|
||||
}
|
||||
/*
|
||||
* XXX This is a problematic interface. We alloc _memory_ which is uncached.
|
||||
@@ -311,7 +372,7 @@ dvma_alloc(int size, unsigned int *pphys)
|
||||
* the routine is higher in food chain.
|
||||
*/
|
||||
static void
|
||||
iommu_init(struct iommu *t)
|
||||
iommu_init(struct iommu *t, unsigned long base)
|
||||
{
|
||||
unsigned int *ptab;
|
||||
int ptsize;
|
||||
@@ -319,7 +380,7 @@ iommu_init(struct iommu *t)
|
||||
unsigned int impl, vers;
|
||||
unsigned int tmp;
|
||||
|
||||
if ((regs = map_io(PHYS_JJ_IOMMU, sizeof(struct iommu_regs))) == 0) {
|
||||
if ((regs = map_io(base, sizeof(struct iommu_regs))) == 0) {
|
||||
DPRINTF("Cannot map IOMMU\n");
|
||||
for (;;) { }
|
||||
}
|
||||
|
||||
366
drivers/obio.c
366
drivers/obio.c
@@ -17,69 +17,395 @@
|
||||
#include "libc/vsprintf.h"
|
||||
|
||||
#include "openbios/drivers.h"
|
||||
#include "openbios/nvram.h"
|
||||
#include "obio.h"
|
||||
|
||||
#define REGISTER_NAMED_NODE( name, path ) do { \
|
||||
bind_new_node( name##_flags_, name##_size_, \
|
||||
path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* DECLARE data structures for the nodes. */
|
||||
DECLARE_UNNAMED_NODE( ob_obio, INSTALL_OPEN, sizeof(int) );
|
||||
|
||||
static void
|
||||
ob_zs_init(unsigned long slavio_base)
|
||||
ob_new_obio_device(const char *name, const char *type)
|
||||
{
|
||||
unsigned long zs_addr;
|
||||
|
||||
zs_addr = (unsigned long)map_io(slavio_base + 0x0, 8);
|
||||
push_str("/obio/zs@0,0");
|
||||
push_str("/obio");
|
||||
fword("find-device");
|
||||
fword("new-device");
|
||||
|
||||
PUSH(zs_addr);
|
||||
push_str(name);
|
||||
fword("device-name");
|
||||
|
||||
if (type) {
|
||||
push_str(type);
|
||||
fword("device-type");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
ob_reg(unsigned long base, unsigned long offset, unsigned long size, int map)
|
||||
{
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(sizeof(zs_addr));
|
||||
PUSH(offset);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(size);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
if (map) {
|
||||
unsigned long addr;
|
||||
|
||||
addr = (unsigned long)map_io(base + offset, size);
|
||||
|
||||
PUSH(addr);
|
||||
fword("encode-int");
|
||||
PUSH(4);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("address");
|
||||
fword("property");
|
||||
return addr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
zs_addr = (unsigned long)map_io(slavio_base + 0x00100000, 8);
|
||||
push_str("/obio/zs@0,100000");
|
||||
fword("find-device");
|
||||
|
||||
PUSH(zs_addr);
|
||||
static void
|
||||
ob_intr(int intr)
|
||||
{
|
||||
PUSH(intr);
|
||||
fword("encode-int");
|
||||
PUSH(sizeof(zs_addr));
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("address");
|
||||
push_str("intr");
|
||||
fword("property");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ob_zs_init(unsigned long base, unsigned long offset, int intr, int slave, int keyboard)
|
||||
{
|
||||
ob_new_obio_device("zs", "serial");
|
||||
|
||||
ob_reg(base, offset, ZS_REGS, 1);
|
||||
|
||||
PUSH(slave);
|
||||
fword("encode-int");
|
||||
push_str("slave");
|
||||
fword("property");
|
||||
|
||||
if (keyboard) {
|
||||
PUSH(-1);
|
||||
fword("encode-int");
|
||||
push_str("keyboard");
|
||||
fword("property");
|
||||
|
||||
PUSH(-1);
|
||||
fword("encode-int");
|
||||
push_str("mouse");
|
||||
fword("property");
|
||||
}
|
||||
|
||||
ob_intr(intr);
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
static char *nvram;
|
||||
struct qemu_nvram_v1 nv_info;
|
||||
|
||||
void
|
||||
arch_nvram_get(char *data)
|
||||
{
|
||||
memcpy(data, nvram, NVRAM_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
arch_nvram_put(char *data)
|
||||
{
|
||||
memcpy(nvram, data, NVRAM_SIZE);
|
||||
}
|
||||
|
||||
int
|
||||
arch_nvram_size(void)
|
||||
{
|
||||
return NVRAM_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
ob_nvram_init(unsigned long base, unsigned long offset)
|
||||
{
|
||||
extern uint32_t kernel_image;
|
||||
extern uint32_t kernel_size;
|
||||
extern uint32_t cmdline;
|
||||
extern uint32_t cmdline_size;
|
||||
extern char boot_device;
|
||||
|
||||
ob_new_obio_device("eeprom", NULL);
|
||||
|
||||
nvram = (char *)ob_reg(base, offset, NVRAM_SIZE, 1);
|
||||
|
||||
memcpy(&nv_info, nvram, sizeof(nv_info));
|
||||
|
||||
printk("Nvram id %s, version %d\n", nv_info.id_string, nv_info.version);
|
||||
if (strcmp(nv_info.id_string, "QEMU_BIOS") || nv_info.version != 1) {
|
||||
printk("Unknown nvram, freezing!\n");
|
||||
for (;;);
|
||||
}
|
||||
kernel_image = nv_info.kernel_image;
|
||||
kernel_size = nv_info.kernel_size;
|
||||
cmdline = nv_info.cmdline;
|
||||
cmdline_size = nv_info.cmdline_size;
|
||||
boot_device = nv_info.boot_device;
|
||||
|
||||
push_str("mk48t08");
|
||||
fword("model");
|
||||
|
||||
fword("finish-device");
|
||||
|
||||
push_str("/");
|
||||
fword("find-device");
|
||||
|
||||
PUSH((long)&nvram[NVRAM_IDPROM]);
|
||||
PUSH(32);
|
||||
fword("encode-bytes");
|
||||
push_str("idprom");
|
||||
fword("property");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_obio_open(int *idx)
|
||||
ob_fd_init(unsigned long base, unsigned long offset, int intr)
|
||||
{
|
||||
ob_new_obio_device("SUNW,fdtwo", "block");
|
||||
|
||||
ob_reg(base, offset, FD_REGS, 0);
|
||||
|
||||
ob_intr(intr);
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ob_sconfig_init(unsigned long base, unsigned long offset)
|
||||
{
|
||||
ob_new_obio_device("slavioconfig", NULL);
|
||||
|
||||
ob_reg(base, offset, SCONFIG_REGS, 0);
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_auxio_init(unsigned long base, unsigned long offset)
|
||||
{
|
||||
ob_new_obio_device("auxio", NULL);
|
||||
|
||||
ob_reg(base, offset, AUXIO_REGS, 0);
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_power_init(unsigned long base, unsigned long offset, int intr)
|
||||
{
|
||||
ob_new_obio_device("power", NULL);
|
||||
|
||||
ob_reg(base, offset, POWER_REGS, 0);
|
||||
|
||||
ob_intr(intr);
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_counter_init(unsigned long base, unsigned long offset)
|
||||
{
|
||||
volatile struct sun4m_timer_regs *regs;
|
||||
|
||||
ob_new_obio_device("counter", NULL);
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(offset);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(COUNTER_REGS);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(offset + 0x10000);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(COUNTER_REGS);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
fword("finish-device");
|
||||
|
||||
regs = map_io(base + offset, sizeof(*regs));
|
||||
regs->l10_timer_limit = (((1000000/100) + 1) << 10);
|
||||
regs->cpu_timers[0].l14_timer_limit = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ob_interrupt_init(unsigned long base, unsigned long offset)
|
||||
{
|
||||
volatile struct sun4m_intregs *regs;
|
||||
|
||||
ob_new_obio_device("interrupt", NULL);
|
||||
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(offset);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(INTERRUPT_REGS);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(offset + 0x10000);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(INTERRUPT_REGS);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("reg");
|
||||
fword("property");
|
||||
|
||||
fword("finish-device");
|
||||
|
||||
regs = map_io(base + offset, sizeof(*regs));
|
||||
regs->set = ~SUN4M_INT_MASKALL;
|
||||
regs->cpu_intregs[0].clear = ~0x17fff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ob_obio_open(__attribute__((unused))int *idx)
|
||||
{
|
||||
int ret=1;
|
||||
RET ( -ret );
|
||||
}
|
||||
|
||||
static void
|
||||
ob_obio_close(int *idx)
|
||||
ob_obio_close(__attribute__((unused))int *idx)
|
||||
{
|
||||
selfword("close-deblocker");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_obio_initialize(int *idx)
|
||||
ob_obio_initialize(__attribute__((unused))int *idx)
|
||||
{
|
||||
push_str("/");
|
||||
fword("find-device");
|
||||
fword("new-device");
|
||||
|
||||
push_str("obio");
|
||||
fword("device-name");
|
||||
|
||||
push_str("hierarchical");
|
||||
fword("device-type");
|
||||
|
||||
PUSH(2);
|
||||
fword("encode-int");
|
||||
push_str("#address-cells");
|
||||
fword("property");
|
||||
|
||||
PUSH(1);
|
||||
fword("encode-int");
|
||||
push_str("#size-cells");
|
||||
fword("property");
|
||||
|
||||
fword("finish-device");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_set_obio_ranges(unsigned long base)
|
||||
{
|
||||
push_str("/obio");
|
||||
fword("find-device");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(0);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(base);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
PUSH(SLAVIO_SIZE);
|
||||
fword("encode-int");
|
||||
fword("encode+");
|
||||
push_str("ranges");
|
||||
fword("property");
|
||||
}
|
||||
|
||||
static void
|
||||
ob_obio_decodeunit(__attribute__((unused)) int *idx)
|
||||
{
|
||||
fword("decode-unit-sbus");
|
||||
}
|
||||
|
||||
|
||||
NODE_METHODS(ob_obio_node) = {
|
||||
static void
|
||||
ob_obio_encodeunit(__attribute__((unused)) int *idx)
|
||||
{
|
||||
fword("encode-unit-sbus");
|
||||
}
|
||||
|
||||
NODE_METHODS(ob_obio) = {
|
||||
{ NULL, ob_obio_initialize },
|
||||
{ "open", ob_obio_open },
|
||||
{ "close", ob_obio_close },
|
||||
{ "encode-unit", ob_obio_encodeunit },
|
||||
{ "decode-unit", ob_obio_decodeunit },
|
||||
};
|
||||
|
||||
|
||||
int ob_obio_init(unsigned long slavio_base)
|
||||
int
|
||||
ob_obio_init(unsigned long slavio_base)
|
||||
{
|
||||
|
||||
//printk("Initializing OBIO devices...\n");
|
||||
#if 0 // XXX
|
||||
REGISTER_NAMED_NODE(ob_obio, "/obio");
|
||||
device_end();
|
||||
ob_set_obio_ranges(slavio_base);
|
||||
#endif
|
||||
|
||||
ob_zs_init(slavio_base);
|
||||
ob_zs_init(slavio_base, SLAVIO_ZS, ZS_INTR, 1, 1);
|
||||
|
||||
ob_zs_init(slavio_base, SLAVIO_ZS1, ZS_INTR, 0, 0);
|
||||
|
||||
ob_nvram_init(slavio_base, SLAVIO_NVRAM);
|
||||
|
||||
ob_fd_init(slavio_base, SLAVIO_FD, FD_INTR);
|
||||
|
||||
ob_sconfig_init(slavio_base, SLAVIO_SCONFIG);
|
||||
|
||||
ob_auxio_init(slavio_base, SLAVIO_AUXIO);
|
||||
|
||||
ob_power_init(slavio_base, SLAVIO_POWER, POWER_INTR);
|
||||
|
||||
ob_counter_init(slavio_base, SLAVIO_COUNTER);
|
||||
|
||||
ob_interrupt_init(slavio_base, SLAVIO_INTERRUPT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
187
drivers/obio.h
Normal file
187
drivers/obio.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/* Addresses, interrupt numbers, register sizes */
|
||||
|
||||
#define SLAVIO_ZS 0x00000000
|
||||
#define SLAVIO_ZS1 0x00100000
|
||||
#define ZS_INTR 0x2c
|
||||
#define ZS_REGS 8
|
||||
|
||||
#define SLAVIO_NVRAM 0x00200000
|
||||
#define NVRAM_SIZE 0x2000
|
||||
#define NVRAM_IDPROM 0x1fd8
|
||||
|
||||
#define SLAVIO_FD 0x00400000
|
||||
#define FD_REGS 15
|
||||
#define FD_INTR 0x2b
|
||||
|
||||
#define SLAVIO_SCONFIG 0x00800000
|
||||
#define SCONFIG_REGS 1
|
||||
|
||||
#define SLAVIO_AUXIO 0x00900000
|
||||
#define AUXIO_REGS 1
|
||||
|
||||
#define SLAVIO_POWER 0x00910000
|
||||
#define POWER_REGS 1
|
||||
#define POWER_INTR 0x22
|
||||
|
||||
#define SLAVIO_COUNTER 0x00d00000
|
||||
#define COUNTER_REGS 0x10
|
||||
|
||||
#define SLAVIO_INTERRUPT 0x00e00000
|
||||
#define INTERRUPT_REGS 0x10
|
||||
|
||||
#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 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
|
||||
|
||||
/* linux/include/asm-sparc/timer.h */
|
||||
|
||||
/* A sun4m has two blocks of registers which are probably of the same
|
||||
* structure. LSI Logic's L64851 is told to _decrement_ from the limit
|
||||
* value. Aurora behaves similarly but its limit value is compacted in
|
||||
* other fashion (it's wider). Documented fields are defined here.
|
||||
*/
|
||||
|
||||
/* As with the interrupt register, we have two classes of timer registers
|
||||
* which are per-cpu and master. Per-cpu timers only hit that cpu and are
|
||||
* only level 14 ticks, master timer hits all cpus and is level 10.
|
||||
*/
|
||||
|
||||
#define SUN4M_PRM_CNT_L 0x80000000
|
||||
#define SUN4M_PRM_CNT_LVALUE 0x7FFFFC00
|
||||
|
||||
struct sun4m_timer_percpu_info {
|
||||
__volatile__ unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
|
||||
__volatile__ unsigned int l14_cur_count;
|
||||
|
||||
/* This register appears to be write only and/or inaccessible
|
||||
* on Uni-Processor sun4m machines.
|
||||
*/
|
||||
__volatile__ unsigned int l14_limit_noclear; /* Data access error is here */
|
||||
|
||||
__volatile__ unsigned int cntrl; /* =1 after POST on Aurora */
|
||||
__volatile__ unsigned char space[PAGE_SIZE - 16];
|
||||
};
|
||||
|
||||
struct sun4m_timer_regs {
|
||||
struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS];
|
||||
volatile unsigned int l10_timer_limit;
|
||||
volatile unsigned int l10_cur_count;
|
||||
|
||||
/* Again, this appears to be write only and/or inaccessible
|
||||
* on uni-processor sun4m machines.
|
||||
*/
|
||||
volatile unsigned int l10_limit_noclear;
|
||||
|
||||
/* This register too, it must be magic. */
|
||||
volatile unsigned int foobar;
|
||||
|
||||
volatile unsigned int cfg; /* equals zero at boot time... */
|
||||
};
|
||||
|
||||
/*
|
||||
* Registers of hardware timer in sun4m.
|
||||
*/
|
||||
struct sun4m_timer_percpu {
|
||||
volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
|
||||
volatile unsigned int l14_cur_count;
|
||||
};
|
||||
|
||||
struct sun4m_timer_global {
|
||||
volatile unsigned int l10_timer_limit;
|
||||
volatile unsigned int l10_cur_count;
|
||||
};
|
||||
|
||||
/* linux/include/asm-sparc/irq.h */
|
||||
|
||||
/* These registers are used for sending/receiving irqs from/to
|
||||
* different cpu's.
|
||||
*/
|
||||
struct sun4m_intreg_percpu {
|
||||
unsigned int tbt; /* Interrupts still pending for this cpu. */
|
||||
|
||||
/* These next two registers are WRITE-ONLY and are only
|
||||
* "on bit" sensitive, "off bits" written have NO affect.
|
||||
*/
|
||||
unsigned int clear; /* Clear this cpus irqs here. */
|
||||
unsigned int set; /* Set this cpus irqs here. */
|
||||
unsigned char space[PAGE_SIZE - 12];
|
||||
};
|
||||
|
||||
/*
|
||||
* djhr
|
||||
* Actually the clear and set fields in this struct are misleading..
|
||||
* according to the SLAVIO manual (and the same applies for the SEC)
|
||||
* the clear field clears bits in the mask which will ENABLE that IRQ
|
||||
* the set field sets bits in the mask to DISABLE the IRQ.
|
||||
*
|
||||
* Also the undirected_xx address in the SLAVIO is defined as
|
||||
* RESERVED and write only..
|
||||
*
|
||||
* DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
|
||||
* sun4m machines, for MP the layout makes more sense.
|
||||
*/
|
||||
struct sun4m_intregs {
|
||||
struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
|
||||
unsigned int tbt; /* IRQ's that are still pending. */
|
||||
unsigned int irqs; /* Master IRQ bits. */
|
||||
|
||||
/* Again, like the above, two these registers are WRITE-ONLY. */
|
||||
unsigned int clear; /* Clear master IRQ's by setting bits here. */
|
||||
unsigned int set; /* Set master IRQ's by setting bits here. */
|
||||
|
||||
/* This register is both READ and WRITE. */
|
||||
unsigned int undirected_target; /* Which cpu gets undirected irqs. */
|
||||
};
|
||||
|
||||
/* Dave Redman (djhr@tadpole.co.uk)
|
||||
* The sun4m interrupt registers.
|
||||
*/
|
||||
#define SUN4M_INT_ENABLE 0x80000000
|
||||
#define SUN4M_INT_E14 0x00000080
|
||||
#define SUN4M_INT_E10 0x00080000
|
||||
|
||||
#define SUN4M_HARD_INT(x) (0x000000001 << (x))
|
||||
#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
|
||||
|
||||
#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
|
||||
#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
|
||||
#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */
|
||||
#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */
|
||||
#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
|
||||
#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
|
||||
#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
|
||||
#define SUN4M_INT_REALTIME 0x00080000 /* system timer */
|
||||
#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */
|
||||
#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */
|
||||
#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */
|
||||
#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
|
||||
#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */
|
||||
#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
|
||||
|
||||
Reference in New Issue
Block a user