hw/sparc64: add basic NBSR implementation (only traces calls)
* IOHub implementation must be moved from e2k branch where it's almost works Signed-off-by: Alibek Omarov <a1ba.omarov@gmail.com>
This commit is contained in:
parent
1a7bf88bfb
commit
af82362cd6
@ -12,23 +12,152 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/char/escc.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pci_bridge.h"
|
||||
#include "hw/pci/pci_bus.h"
|
||||
#include "hw/pci/pci_host.h"
|
||||
#include "hw/sparc/sparc64.h"
|
||||
#include "hw/sparc/sun4u_iommu.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "cpu.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define ELBRUS_GPIO_START 0xf1200000ULL // TODO: verify this address
|
||||
#define ELBRUS_SCC_START 0xf1100000ULL // TODO: verify this address
|
||||
#define ELBRUS_PROM_START 0xf0000000ULL // prom seems to be fine to be loaded from this address
|
||||
#define PROM_SIZE_MAX (8 * MiB)
|
||||
// memory map
|
||||
#define PROM_BASE 0xFFFF000000UL // bootloader
|
||||
#define PCIIO_BASE 0xFF20000000UL
|
||||
#define PEXCFG_BASE 0xFF10000000UL // pci express configuration registers
|
||||
#define NBSR_BASE 0xFE00000000UL // north bridge system registers (?)
|
||||
#define NBSR_SIZE (1 * MiB)
|
||||
|
||||
#define PROM_SIZE_MAX (16 * MiB)
|
||||
#define PROM_FILENAME "_4R.bin"
|
||||
|
||||
#define ESCC_CLOCK 4915200 // TODO: why?
|
||||
|
||||
typedef struct ElbrusBoardState {
|
||||
#define TYPE_E90S MACHINE_TYPE_NAME("e90s")
|
||||
#define TYPE_E90S_NBSR "e90s-nbsr"
|
||||
#define TYPE_E90S_IOHUB "e90s-iohub"
|
||||
|
||||
typedef struct E90SState {
|
||||
MemoryRegion prom;
|
||||
} ElbrusBoardState;
|
||||
MemoryRegion nbsr;
|
||||
} E90SState;
|
||||
DECLARE_INSTANCE_CHECKER(E90SState, E90S, TYPE_E90S)
|
||||
|
||||
typedef struct NBSRState {
|
||||
SysBusDevice parent_obj;
|
||||
MemoryRegion region;
|
||||
} NBSRState;
|
||||
DECLARE_INSTANCE_CHECKER(NBSRState, NBSR, TYPE_E90S_NBSR)
|
||||
|
||||
typedef struct IOHubState {
|
||||
PCIHostState parent_obj;
|
||||
|
||||
MemoryRegion pci_cfg;
|
||||
MemoryRegion pci_io;
|
||||
MemoryRegion pci_mmio;
|
||||
} IOHubState;
|
||||
DECLARE_INSTANCE_CHECKER(IOHubState, IOHUB, TYPE_E90S_IOHUB)
|
||||
|
||||
/* North Bridge System Registers */
|
||||
static uint64_t nbsr_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
trace_nbsr_read(addr, 0, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nbsr_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
trace_nbsr_write(addr, val, size);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nbsr_ops = {
|
||||
.read = nbsr_read,
|
||||
.write = nbsr_write,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static void nbsr_realize(DeviceState *d, Error **errp)
|
||||
{
|
||||
NBSRState *nbsr = NBSR(d);
|
||||
|
||||
memory_region_init_io(&nbsr->region, OBJECT(d),
|
||||
&nbsr_ops, OBJECT(d), "e90s.nbsr", NBSR_SIZE);
|
||||
memory_region_add_subregion(get_system_memory(), NBSR_BASE,
|
||||
&nbsr->region);
|
||||
}
|
||||
|
||||
static void nbsr_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
dc->realize = nbsr_realize;
|
||||
}
|
||||
|
||||
static const TypeInfo nbsr_info = {
|
||||
.name = TYPE_E90S_NBSR,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(NBSRState),
|
||||
.class_init = nbsr_class_init,
|
||||
};
|
||||
|
||||
/* IOHub */
|
||||
/* TODO: move to hw/pci/ */
|
||||
static void pci_iohub_set_irq(void *opaque, int irq_num, int level)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
|
||||
static int pci_iohub_map_irq(PCIDevice *pci_dev, int irq_num)
|
||||
{
|
||||
return irq_num;
|
||||
}
|
||||
|
||||
static void iohub_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
IOHubState *s = IOHUB(dev);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
|
||||
|
||||
phb->bus = pci_register_root_bus(dev, "pci", pci_iohub_set_irq, pci_iohub_map_irq,
|
||||
s, &s->pci_mmio, &s->pci_io, 0, 0x40, TYPE_PCI_BUS);
|
||||
|
||||
// pci_create_simple(phb->bus, 0, TYPE_IOHUB_PCI_DEVICE);
|
||||
}
|
||||
|
||||
static void iohub_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = iohub_realize;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
dc->fw_name = "pci";
|
||||
}
|
||||
|
||||
const TypeInfo iohub_info = {
|
||||
.name = TYPE_E90S_IOHUB,
|
||||
.parent = TYPE_PCI_HOST_BRIDGE,
|
||||
.instance_size = sizeof(IOHubState),
|
||||
.class_init = iohub_class_init,
|
||||
};
|
||||
|
||||
static void pci_init(E90SState *e90s)
|
||||
{
|
||||
#if 0
|
||||
dev = qdev_new(TYPE_ESCC);
|
||||
qdev_prop_set_uint32(dev, "disabled", 0);
|
||||
qdev_prop_set_uint32(dev, "frequency", ESCC_CLOCK);
|
||||
qdev_prop_set_uint32(dev, "it_shift", 0);
|
||||
qdev_prop_set_chr(dev, "chrB", serial_hd(1));
|
||||
qdev_prop_set_chr(dev, "chrA", serial_hd(0));
|
||||
qdev_prop_set_uint32(dev, "chnBtype", escc_serial);
|
||||
qdev_prop_set_uint32(dev, "chnAtype", escc_serial);
|
||||
|
||||
sb = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize_and_unref(sb, &error_fatal);
|
||||
sysbus_mmio_map(sb, 0, ELBRUS_SCC_START);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Boot PROM */
|
||||
static void prom_init(hwaddr addr, const char *bios_name)
|
||||
@ -56,33 +185,26 @@ static void prom_init(hwaddr addr, const char *bios_name)
|
||||
|
||||
static void e90s_init(MachineState *machine)
|
||||
{
|
||||
ElbrusBoardState *s = g_new(ElbrusBoardState, 1);
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
DeviceState *dev;
|
||||
SysBusDevice *sb;
|
||||
E90SState *s = E90S(machine);
|
||||
DeviceState *dev;
|
||||
SysBusDevice *sb;
|
||||
// SPARCCPU *cpu;
|
||||
|
||||
/* init CPUs */
|
||||
sparc64_cpu_devinit(machine->cpu_type, ELBRUS_PROM_START);
|
||||
sparc64_cpu_devinit(machine->cpu_type, PROM_BASE);
|
||||
|
||||
memory_region_add_subregion(sysmem, 0, machine->ram);
|
||||
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
|
||||
|
||||
memory_region_init_ram(&s->prom, NULL, "e90s.prom", PROM_SIZE_MAX, &error_fatal);
|
||||
memory_region_add_subregion(sysmem, ELBRUS_PROM_START, &s->prom);
|
||||
prom_init(ELBRUS_PROM_START, machine->firmware);
|
||||
|
||||
dev = qdev_new(TYPE_ESCC);
|
||||
qdev_prop_set_uint32(dev, "disabled", 0);
|
||||
qdev_prop_set_uint32(dev, "frequency", ESCC_CLOCK);
|
||||
qdev_prop_set_uint32(dev, "it_shift", 1);
|
||||
qdev_prop_set_chr(dev, "chrB", serial_hd(1));
|
||||
qdev_prop_set_chr(dev, "chrA", serial_hd(0));
|
||||
qdev_prop_set_uint32(dev, "chnBtype", escc_serial);
|
||||
qdev_prop_set_uint32(dev, "chnAtype", escc_serial);
|
||||
memory_region_init_ram(&s->prom, OBJECT(machine),
|
||||
"e90s.prom", PROM_SIZE_MAX, &error_fatal);
|
||||
memory_region_add_subregion(get_system_memory(), PROM_BASE, &s->prom);
|
||||
prom_init(PROM_BASE, machine->firmware);
|
||||
|
||||
sb = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize_and_unref(sb, &error_fatal);
|
||||
sysbus_mmio_map(sb, 0, ELBRUS_SCC_START);
|
||||
dev = qdev_new(TYPE_E90S_NBSR);
|
||||
sb = SYS_BUS_DEVICE(dev);
|
||||
sysbus_realize_and_unref(sb, &error_fatal);
|
||||
|
||||
pci_init(s);
|
||||
}
|
||||
|
||||
static void e90s_class_init(ObjectClass *oc, void *data)
|
||||
@ -97,7 +219,7 @@ static void e90s_class_init(ObjectClass *oc, void *data)
|
||||
mc->default_ram_id = "e90s.ram";
|
||||
}
|
||||
|
||||
static const TypeInfo e90s_type = {
|
||||
static const TypeInfo e90s_info = {
|
||||
.name = MACHINE_TYPE_NAME("e90s"),
|
||||
.parent = TYPE_MACHINE,
|
||||
.class_init = e90s_class_init,
|
||||
@ -105,7 +227,10 @@ static const TypeInfo e90s_type = {
|
||||
|
||||
static void e90s_register_types(void)
|
||||
{
|
||||
type_register_static(&e90s_type);
|
||||
type_register_static(&nbsr_info);
|
||||
// type_register_static(&iohub_info);
|
||||
|
||||
type_register_static(&e90s_info);
|
||||
}
|
||||
|
||||
type_init(e90s_register_types)
|
||||
|
@ -1,5 +1,9 @@
|
||||
# See docs/devel/tracing.rst for syntax documentation.
|
||||
|
||||
# e90s.c
|
||||
nbsr_read(uint64_t addr, uint64_t val, int size) "addr: 0x%"PRIx64" val: 0x%"PRIx64" size: %d"
|
||||
nbsr_write(uint64_t addr, uint64_t val, int size) "addr: 0x%"PRIx64" val: 0x%"PRIx64" size: %d"
|
||||
|
||||
# sun4u.c
|
||||
ebus_isa_irq_handler(int n, int level) "Set ISA IRQ %d level %d"
|
||||
|
||||
@ -21,3 +25,4 @@ sparc64_cpu_tick_set_count(const char *name, uint64_t real_count, const char *np
|
||||
sparc64_cpu_tick_get_count(const char *name, uint64_t real_count, const char *npt, void *p) "%s get_count count=0x%"PRIx64" (npt %s) p=%p"
|
||||
sparc64_cpu_tick_set_limit(const char *name, uint64_t real_limit, const char *dis, void *p, uint64_t limit, uint64_t t, uint64_t dt) "%s set_limit limit=0x%"PRIx64 " (%s) p=%p called with limit=0x%"PRIx64" at 0x%"PRIx64" (delta=0x%"PRIx64")"
|
||||
sparc64_cpu_tick_set_limit_zero(const char *name) "%s set_limit limit=ZERO - not starting timer"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user