-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Mike Frysinger <[email protected]>
- Loading branch information
Showing
15 changed files
with
1,326 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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]> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Oops, something went wrong.