Skip to content

Commit

Permalink
Blackfin: initial set of models
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Frysinger <[email protected]>
  • Loading branch information
vapier committed Dec 1, 2023
1 parent 40844d6 commit eeb9263
Show file tree
Hide file tree
Showing 15 changed files with 1,326 additions and 0 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ Blackfin
M: Mike Frysinger <[email protected]>
S: Maintained
F: target/bfin/
F: hw/bfin/

CRIS TCG CPUs
M: Edgar E. Iglesias <[email protected]>
Expand Down
164 changes: 164 additions & 0 deletions hw/bfin/bfin_boards.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Blackfin board models
*
* Copyright 2007-2023 Mike Frysinger
* Copyright 2007-2011 Analog Devices, Inc.
*
* Licensed under the Lesser GPL 2 or later.
*/

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/bfin/bfin_uart.h"
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/sysbus.h"
#include "chardev/char-fe.h"
#include "sysemu/sysemu.h"
#include "exec/address-spaces.h"
#include "migration/vmstate.h"

struct bfin_memory_layout {
hwaddr addr;
ram_addr_t len;
const char *name;
};
#define LAYOUT(_addr, _len, _name) { .addr = _addr, .len = _len, .name = _name, }

static const struct bfin_memory_layout bf537_mem[] =
{
LAYOUT(0xFF800000, 0x4000, "L1 Data A"),
LAYOUT(0xFF804000, 0x4000, "Data A Cache"),
LAYOUT(0xFF900000, 0x4000, "Data B"),
LAYOUT(0xFF904000, 0x4000, "Data B Cache"),
LAYOUT(0xFFA00000, 0x8000, "Inst A"),
LAYOUT(0xFFA08000, 0x4000, "Inst B"),
LAYOUT(0xFFA10000, 0x4000, "Inst Cache"),
LAYOUT(0, 0, "SDRAM"),
};

static void bfin_memory_init(const struct bfin_memory_layout mem_layout[],
MachineState *machine)
{
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *mem;
size_t i;

for (i = 0; mem_layout[i].len; ++i) {
mem = g_new(MemoryRegion, 1);
memory_region_init_ram(mem, NULL, mem_layout[i].name, mem_layout[i].len,
&error_abort);
memory_region_add_subregion(address_space_mem, mem_layout[i].addr, mem);
}

mem = g_new(MemoryRegion, 1);
memory_region_init_ram(mem, NULL, mem_layout[i].name, machine->ram_size,
&error_abort);
memory_region_add_subregion(address_space_mem, mem_layout[i].addr, mem);

/* Address space reserved for on-chip (system) devices */
//mem = g_new(MemoryRegion, 1);
//memory_region_init_io(mem, NULL, NULL, "System MMRs", 0x200000);
//memory_region_add_subregion(address_space_mem, 0xFFC00000, mem);

/* Address space reserved for on-chip (core) devices */
//mem = g_new(MemoryRegion, 1);
/* TODO: This should be owned by the CPU. */
//memory_region_init_io(mem, NULL, NULL, "Core MMRs", 0x200000);
//memory_region_add_subregion(address_space_mem, 0xFFE00000, mem);
}

static void bfin_device_init(void)
{
/* Core peripherals */
sysbus_create_simple("bfin_mmu", 0xFFE00000, NULL);
sysbus_create_simple("bfin_evt", 0xFFE02000, NULL);
sysbus_create_simple("bfin_trace", 0xFFE06000, NULL);

/* System peripherals */
/* XXX: BF537-specific */
sysbus_create_simple("bfin_pll", 0xFFC00000, NULL);
sysbus_create_simple("bfin_sic", 0xFFC00100, NULL);
bfin_uart_init(0xFFC00400, serial_hd(0));
bfin_uart_init(0xFFC02000, serial_hd(1));
}

static void bfin_common_init(const struct bfin_memory_layout mem_layout[],
MachineState *machine)
{
const char *kernel_filename = machine->kernel_filename;
CPUState *cs;
int n;

bfin_memory_init(mem_layout, machine);
bfin_device_init();

for (n = 0; n < 1 /*TODO: smp_cpus*/; n++) {
cs = CPU(BFIN_CPU(cpu_create(machine->cpu_type)));
if (cs == NULL) {
fprintf(stderr, "Unable to find CPU definition!\n");
exit(1);
}
}

if (kernel_filename) {
uint64_t entry = 0;
const char *kernel_cmdline = machine->kernel_cmdline;
long kernel_size;
/* TODO: Not SMP safe. */
CPUArchState *env;
BlackfinCPU *cpu;

cs = first_cpu;
cpu = BFIN_CPU(cs);
env = &cpu->env;

kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, NULL,
NULL, NULL, 0, ELF_MACHINE, 0, 0);
if (kernel_size < 0) {
kernel_size = load_image_targphys(kernel_filename, 0, machine->ram_size);
}
if (kernel_size < 0) {
fprintf(stderr, "qemu: could not load kernel '%s'\n",
kernel_filename);
exit(1);
}
env->pc = entry;

if (kernel_cmdline) {
pstrcpy_targphys("cmdline", kernel_size, -1, kernel_cmdline);
}
}
}

static void bf537_stamp_init(MachineState *machine)
{
bfin_common_init(bf537_mem, machine);
}

static void bf537_stamp_machine_init(MachineClass *mc)
{
mc->desc = "Analog Devices Blackfin ADSP-BF537 STAMP";
mc->init = bf537_stamp_init;
mc->max_cpus = 1;
mc->default_cpu_type = BLACKFIN_CPU_TYPE_NAME("bf537");
mc->default_ram_size = 64 * MiB;
mc->default_ram_id = "ram";
mc->is_default = 1;
}
DEFINE_MACHINE("bf537-stamp", bf537_stamp_machine_init)

static void bf537_ezkit_machine_init(MachineClass *mc)
{
mc->desc = "Analog Devices Blackfin ADSP-BF537 EZ-KIT";
mc->init = bf537_stamp_init;
mc->max_cpus = 1;
mc->default_cpu_type = BLACKFIN_CPU_TYPE_NAME("bf537");
mc->default_ram_size = 64 * MiB;
mc->default_ram_id = "ram";
}
DEFINE_MACHINE("bf537-ezkit", bf537_ezkit_machine_init)
31 changes: 31 additions & 0 deletions hw/bfin/bfin_devices.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Common Blackfin device model code
*
* Copyright 2007-2023 Mike Frysinger
* Copyright 2007-2011 Analog Devices, Inc.
*
* Licensed under the Lesser GPL 2 or later.
*/

#ifndef BFIN_DEVICES_H
#define BFIN_DEVICES_H

#define mmr_size() (sizeof(BfinMMRState) - mmr_base())
#define mmr_offset(mmr) (offsetof(BfinMMRState, mmr) - mmr_base())
#define mmr_idx(mmr) (mmr_offset(mmr) / 4)
#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")

#define HW_TRACE_WRITE() \
trace_bfin_reg_memory_write(addr + s->iomem.addr, mmr_name(addr), size, \
value)
#define HW_TRACE_READ() \
trace_bfin_reg_memory_read(addr + s->iomem.addr, mmr_name(addr), size)

typedef int16_t bs16;
typedef int32_t bs32;
typedef uint16_t bu16;
typedef uint32_t bu32;

#define BFIN_MMR_16(mmr) mmr, __pad_##mmr

#endif
111 changes: 111 additions & 0 deletions hw/bfin/bfin_dma.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Blackfin Direct Memory Access (DMA) Channel model.
*
* Copyright 2007-2023 Mike Frysinger
* Copyright 2007-2011 Analog Devices, Inc.
*
* Licensed under the Lesser GPL 2 or later.
*/

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "trace-root.h"
#include "bfin_devices.h"

#define TYPE_BFIN_DMA "bfin_dma"
#define BFIN_DMA(obj) OBJECT_CHECK(BfinDMAState, (obj), TYPE_BFIN_DMA)

typedef struct BfinDMAState {
SysBusDevice parent_obj;
MemoryRegion iomem;

/* Order after here is important -- matches hardware MMR layout. */
union {
struct { bu16 ndpl, ndph; };
bu32 next_desc_ptr;
};
union {
struct { bu16 sal, sah; };
bu32 start_addr;
};
bu16 BFIN_MMR_16 (config);
bu32 _pad0;
bu16 BFIN_MMR_16 (x_count);
bs16 BFIN_MMR_16 (x_modify);
bu16 BFIN_MMR_16 (y_count);
bs16 BFIN_MMR_16 (y_modify);
bu32 curr_desc_ptr, curr_addr;
bu16 BFIN_MMR_16 (irq_status);
bu16 BFIN_MMR_16 (peripheral_map);
bu16 BFIN_MMR_16 (curr_x_count);
bu32 _pad1;
bu16 BFIN_MMR_16 (curr_y_count);
bu32 _pad2;
} BfinDMAState;
#define BfinMMRState BfinDMAState
#define mmr_base() offsetof(BfinMMRState, next_desc_ptr)

static const char * const mmr_names[] =
{
"NEXT_DESC_PTR", "START_ADDR", "CONFIG", "<INV>", "X_COUNT", "X_MODIFY",
"Y_COUNT", "Y_MODIFY", "CURR_DESC_PTR", "CURR_ADDR", "IRQ_STATUS",
"PERIPHERAL_MAP", "CURR_X_COUNT", "<INV>", "CURR_Y_COUNT", "<INV>",
};

static void bfin_dma_io_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
BfinDMAState *s = opaque;

HW_TRACE_WRITE();
}

static uint64_t bfin_dma_io_read(void *opaque, hwaddr addr, unsigned size)
{
BfinDMAState *s = opaque;

HW_TRACE_READ();

return 0;
}

static const MemoryRegionOps bfin_dma_io_ops = {
.read = bfin_dma_io_read,
.write = bfin_dma_io_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 2,
.max_access_size = 4,
},
};

static void bfin_dma_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
BfinDMAState *s = BFIN_DMA(dev);

memory_region_init_io(&s->iomem, OBJECT(s), &bfin_dma_io_ops, s, "dma", mmr_size());
sysbus_init_mmio(sbd, &s->iomem);
}

static void bfin_dma_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);

dc->realize = bfin_dma_realize;
}

static TypeInfo bfin_dma_info = {
.name = "bfin_dma",
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BfinDMAState),
.class_init = bfin_dma_class_init,
};

static void bfin_dma_register_types(void)
{
type_register_static(&bfin_dma_info);
}

type_init(bfin_dma_register_types)
Loading

0 comments on commit eeb9263

Please sign in to comment.