Skip to content

Commit ae8fe9a

Browse files
committed
Blackfin: initial set of models
Signed-off-by: Mike Frysinger <[email protected]>
1 parent e171dd5 commit ae8fe9a

File tree

15 files changed

+1326
-0
lines changed

15 files changed

+1326
-0
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ Blackfin
226226
M: Mike Frysinger <[email protected]>
227227
S: Maintained
228228
F: target/bfin/
229+
F: hw/bfin/
229230

230231
CRIS TCG CPUs
231232
M: Edgar E. Iglesias <[email protected]>

hw/bfin/bfin_boards.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
* Blackfin board models
3+
*
4+
* Copyright 2007-2023 Mike Frysinger
5+
* Copyright 2007-2011 Analog Devices, Inc.
6+
*
7+
* Licensed under the Lesser GPL 2 or later.
8+
*/
9+
10+
#include "qemu/osdep.h"
11+
#include "qemu/units.h"
12+
#include "qapi/error.h"
13+
#include "cpu.h"
14+
#include "hw/bfin/bfin_uart.h"
15+
#include "hw/hw.h"
16+
#include "hw/boards.h"
17+
#include "hw/loader.h"
18+
#include "elf.h"
19+
#include "hw/sysbus.h"
20+
#include "chardev/char-fe.h"
21+
#include "sysemu/sysemu.h"
22+
#include "exec/address-spaces.h"
23+
#include "migration/vmstate.h"
24+
25+
struct bfin_memory_layout {
26+
hwaddr addr;
27+
ram_addr_t len;
28+
const char *name;
29+
};
30+
#define LAYOUT(_addr, _len, _name) { .addr = _addr, .len = _len, .name = _name, }
31+
32+
static const struct bfin_memory_layout bf537_mem[] =
33+
{
34+
LAYOUT(0xFF800000, 0x4000, "L1 Data A"),
35+
LAYOUT(0xFF804000, 0x4000, "Data A Cache"),
36+
LAYOUT(0xFF900000, 0x4000, "Data B"),
37+
LAYOUT(0xFF904000, 0x4000, "Data B Cache"),
38+
LAYOUT(0xFFA00000, 0x8000, "Inst A"),
39+
LAYOUT(0xFFA08000, 0x4000, "Inst B"),
40+
LAYOUT(0xFFA10000, 0x4000, "Inst Cache"),
41+
LAYOUT(0, 0, "SDRAM"),
42+
};
43+
44+
static void bfin_memory_init(const struct bfin_memory_layout mem_layout[],
45+
MachineState *machine)
46+
{
47+
MemoryRegion *address_space_mem = get_system_memory();
48+
MemoryRegion *mem;
49+
size_t i;
50+
51+
for (i = 0; mem_layout[i].len; ++i) {
52+
mem = g_new(MemoryRegion, 1);
53+
memory_region_init_ram(mem, NULL, mem_layout[i].name, mem_layout[i].len,
54+
&error_abort);
55+
memory_region_add_subregion(address_space_mem, mem_layout[i].addr, mem);
56+
}
57+
58+
mem = g_new(MemoryRegion, 1);
59+
memory_region_init_ram(mem, NULL, mem_layout[i].name, machine->ram_size,
60+
&error_abort);
61+
memory_region_add_subregion(address_space_mem, mem_layout[i].addr, mem);
62+
63+
/* Address space reserved for on-chip (system) devices */
64+
//mem = g_new(MemoryRegion, 1);
65+
//memory_region_init_io(mem, NULL, NULL, "System MMRs", 0x200000);
66+
//memory_region_add_subregion(address_space_mem, 0xFFC00000, mem);
67+
68+
/* Address space reserved for on-chip (core) devices */
69+
//mem = g_new(MemoryRegion, 1);
70+
/* TODO: This should be owned by the CPU. */
71+
//memory_region_init_io(mem, NULL, NULL, "Core MMRs", 0x200000);
72+
//memory_region_add_subregion(address_space_mem, 0xFFE00000, mem);
73+
}
74+
75+
static void bfin_device_init(void)
76+
{
77+
/* Core peripherals */
78+
sysbus_create_simple("bfin_mmu", 0xFFE00000, NULL);
79+
sysbus_create_simple("bfin_evt", 0xFFE02000, NULL);
80+
sysbus_create_simple("bfin_trace", 0xFFE06000, NULL);
81+
82+
/* System peripherals */
83+
/* XXX: BF537-specific */
84+
sysbus_create_simple("bfin_pll", 0xFFC00000, NULL);
85+
sysbus_create_simple("bfin_sic", 0xFFC00100, NULL);
86+
bfin_uart_init(0xFFC00400, serial_hd(0));
87+
bfin_uart_init(0xFFC02000, serial_hd(1));
88+
}
89+
90+
static void bfin_common_init(const struct bfin_memory_layout mem_layout[],
91+
MachineState *machine)
92+
{
93+
const char *kernel_filename = machine->kernel_filename;
94+
CPUState *cs;
95+
int n;
96+
97+
bfin_memory_init(mem_layout, machine);
98+
bfin_device_init();
99+
100+
for (n = 0; n < 1 /*TODO: smp_cpus*/; n++) {
101+
cs = CPU(BFIN_CPU(cpu_create(machine->cpu_type)));
102+
if (cs == NULL) {
103+
fprintf(stderr, "Unable to find CPU definition!\n");
104+
exit(1);
105+
}
106+
}
107+
108+
if (kernel_filename) {
109+
uint64_t entry = 0;
110+
const char *kernel_cmdline = machine->kernel_cmdline;
111+
long kernel_size;
112+
/* TODO: Not SMP safe. */
113+
CPUArchState *env;
114+
BlackfinCPU *cpu;
115+
116+
cs = first_cpu;
117+
cpu = BFIN_CPU(cs);
118+
env = &cpu->env;
119+
120+
kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, NULL,
121+
NULL, NULL, 0, ELF_MACHINE, 0, 0);
122+
if (kernel_size < 0) {
123+
kernel_size = load_image_targphys(kernel_filename, 0, machine->ram_size);
124+
}
125+
if (kernel_size < 0) {
126+
fprintf(stderr, "qemu: could not load kernel '%s'\n",
127+
kernel_filename);
128+
exit(1);
129+
}
130+
env->pc = entry;
131+
132+
if (kernel_cmdline) {
133+
pstrcpy_targphys("cmdline", kernel_size, -1, kernel_cmdline);
134+
}
135+
}
136+
}
137+
138+
static void bf537_stamp_init(MachineState *machine)
139+
{
140+
bfin_common_init(bf537_mem, machine);
141+
}
142+
143+
static void bf537_stamp_machine_init(MachineClass *mc)
144+
{
145+
mc->desc = "Analog Devices Blackfin ADSP-BF537 STAMP";
146+
mc->init = bf537_stamp_init;
147+
mc->max_cpus = 1;
148+
mc->default_cpu_type = BLACKFIN_CPU_TYPE_NAME("bf537");
149+
mc->default_ram_size = 64 * MiB;
150+
mc->default_ram_id = "ram";
151+
mc->is_default = 1;
152+
}
153+
DEFINE_MACHINE("bf537-stamp", bf537_stamp_machine_init)
154+
155+
static void bf537_ezkit_machine_init(MachineClass *mc)
156+
{
157+
mc->desc = "Analog Devices Blackfin ADSP-BF537 EZ-KIT";
158+
mc->init = bf537_stamp_init;
159+
mc->max_cpus = 1;
160+
mc->default_cpu_type = BLACKFIN_CPU_TYPE_NAME("bf537");
161+
mc->default_ram_size = 64 * MiB;
162+
mc->default_ram_id = "ram";
163+
}
164+
DEFINE_MACHINE("bf537-ezkit", bf537_ezkit_machine_init)

hw/bfin/bfin_devices.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Common Blackfin device model code
3+
*
4+
* Copyright 2007-2023 Mike Frysinger
5+
* Copyright 2007-2011 Analog Devices, Inc.
6+
*
7+
* Licensed under the Lesser GPL 2 or later.
8+
*/
9+
10+
#ifndef BFIN_DEVICES_H
11+
#define BFIN_DEVICES_H
12+
13+
#define mmr_size() (sizeof(BfinMMRState) - mmr_base())
14+
#define mmr_offset(mmr) (offsetof(BfinMMRState, mmr) - mmr_base())
15+
#define mmr_idx(mmr) (mmr_offset(mmr) / 4)
16+
#define mmr_name(off) (mmr_names[(off) / 4] ? : "<INV>")
17+
18+
#define HW_TRACE_WRITE() \
19+
trace_bfin_reg_memory_write(addr + s->iomem.addr, mmr_name(addr), size, \
20+
value)
21+
#define HW_TRACE_READ() \
22+
trace_bfin_reg_memory_read(addr + s->iomem.addr, mmr_name(addr), size)
23+
24+
typedef int16_t bs16;
25+
typedef int32_t bs32;
26+
typedef uint16_t bu16;
27+
typedef uint32_t bu32;
28+
29+
#define BFIN_MMR_16(mmr) mmr, __pad_##mmr
30+
31+
#endif

hw/bfin/bfin_dma.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Blackfin Direct Memory Access (DMA) Channel model.
3+
*
4+
* Copyright 2007-2023 Mike Frysinger
5+
* Copyright 2007-2011 Analog Devices, Inc.
6+
*
7+
* Licensed under the Lesser GPL 2 or later.
8+
*/
9+
10+
#include "qemu/osdep.h"
11+
#include "hw/hw.h"
12+
#include "hw/sysbus.h"
13+
#include "trace-root.h"
14+
#include "bfin_devices.h"
15+
16+
#define TYPE_BFIN_DMA "bfin_dma"
17+
#define BFIN_DMA(obj) OBJECT_CHECK(BfinDMAState, (obj), TYPE_BFIN_DMA)
18+
19+
typedef struct BfinDMAState {
20+
SysBusDevice parent_obj;
21+
MemoryRegion iomem;
22+
23+
/* Order after here is important -- matches hardware MMR layout. */
24+
union {
25+
struct { bu16 ndpl, ndph; };
26+
bu32 next_desc_ptr;
27+
};
28+
union {
29+
struct { bu16 sal, sah; };
30+
bu32 start_addr;
31+
};
32+
bu16 BFIN_MMR_16 (config);
33+
bu32 _pad0;
34+
bu16 BFIN_MMR_16 (x_count);
35+
bs16 BFIN_MMR_16 (x_modify);
36+
bu16 BFIN_MMR_16 (y_count);
37+
bs16 BFIN_MMR_16 (y_modify);
38+
bu32 curr_desc_ptr, curr_addr;
39+
bu16 BFIN_MMR_16 (irq_status);
40+
bu16 BFIN_MMR_16 (peripheral_map);
41+
bu16 BFIN_MMR_16 (curr_x_count);
42+
bu32 _pad1;
43+
bu16 BFIN_MMR_16 (curr_y_count);
44+
bu32 _pad2;
45+
} BfinDMAState;
46+
#define BfinMMRState BfinDMAState
47+
#define mmr_base() offsetof(BfinMMRState, next_desc_ptr)
48+
49+
static const char * const mmr_names[] =
50+
{
51+
"NEXT_DESC_PTR", "START_ADDR", "CONFIG", "<INV>", "X_COUNT", "X_MODIFY",
52+
"Y_COUNT", "Y_MODIFY", "CURR_DESC_PTR", "CURR_ADDR", "IRQ_STATUS",
53+
"PERIPHERAL_MAP", "CURR_X_COUNT", "<INV>", "CURR_Y_COUNT", "<INV>",
54+
};
55+
56+
static void bfin_dma_io_write(void *opaque, hwaddr addr,
57+
uint64_t value, unsigned size)
58+
{
59+
BfinDMAState *s = opaque;
60+
61+
HW_TRACE_WRITE();
62+
}
63+
64+
static uint64_t bfin_dma_io_read(void *opaque, hwaddr addr, unsigned size)
65+
{
66+
BfinDMAState *s = opaque;
67+
68+
HW_TRACE_READ();
69+
70+
return 0;
71+
}
72+
73+
static const MemoryRegionOps bfin_dma_io_ops = {
74+
.read = bfin_dma_io_read,
75+
.write = bfin_dma_io_write,
76+
.endianness = DEVICE_NATIVE_ENDIAN,
77+
.valid = {
78+
.min_access_size = 2,
79+
.max_access_size = 4,
80+
},
81+
};
82+
83+
static void bfin_dma_realize(DeviceState *dev, Error **errp)
84+
{
85+
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
86+
BfinDMAState *s = BFIN_DMA(dev);
87+
88+
memory_region_init_io(&s->iomem, OBJECT(s), &bfin_dma_io_ops, s, "dma", mmr_size());
89+
sysbus_init_mmio(sbd, &s->iomem);
90+
}
91+
92+
static void bfin_dma_class_init(ObjectClass *klass, void *data)
93+
{
94+
DeviceClass *dc = DEVICE_CLASS(klass);
95+
96+
dc->realize = bfin_dma_realize;
97+
}
98+
99+
static TypeInfo bfin_dma_info = {
100+
.name = "bfin_dma",
101+
.parent = TYPE_SYS_BUS_DEVICE,
102+
.instance_size = sizeof(BfinDMAState),
103+
.class_init = bfin_dma_class_init,
104+
};
105+
106+
static void bfin_dma_register_types(void)
107+
{
108+
type_register_static(&bfin_dma_info);
109+
}
110+
111+
type_init(bfin_dma_register_types)

0 commit comments

Comments
 (0)