From eeb9263056c6406b38e3e017ef4f1eedce56aae0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 13 Jul 2012 22:05:42 +0100 Subject: [PATCH] Blackfin: initial set of models Signed-off-by: Mike Frysinger --- MAINTAINERS | 1 + hw/bfin/bfin_boards.c | 164 +++++++++++++++++++++ hw/bfin/bfin_devices.h | 31 ++++ hw/bfin/bfin_dma.c | 111 ++++++++++++++ hw/bfin/bfin_evt.c | 94 ++++++++++++ hw/bfin/bfin_mmu.c | 133 +++++++++++++++++ hw/bfin/bfin_pll.c | 129 +++++++++++++++++ hw/bfin/bfin_sic.c | 123 ++++++++++++++++ hw/bfin/bfin_trace.c | 148 +++++++++++++++++++ hw/bfin/bfin_uart.c | 320 +++++++++++++++++++++++++++++++++++++++++ hw/bfin/bfin_uart.h | 46 ++++++ hw/bfin/meson.build | 13 ++ hw/meson.build | 1 + target/bfin/helper.c | 8 ++ trace-events | 4 + 15 files changed, 1326 insertions(+) create mode 100644 hw/bfin/bfin_boards.c create mode 100644 hw/bfin/bfin_devices.h create mode 100644 hw/bfin/bfin_dma.c create mode 100644 hw/bfin/bfin_evt.c create mode 100644 hw/bfin/bfin_mmu.c create mode 100644 hw/bfin/bfin_pll.c create mode 100644 hw/bfin/bfin_sic.c create mode 100644 hw/bfin/bfin_trace.c create mode 100644 hw/bfin/bfin_uart.c create mode 100644 hw/bfin/bfin_uart.h create mode 100644 hw/bfin/meson.build diff --git a/MAINTAINERS b/MAINTAINERS index 921f962724d79..a8afccd48b668 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -227,6 +227,7 @@ Blackfin M: Mike Frysinger S: Maintained F: target/bfin/ +F: hw/bfin/ CRIS TCG CPUs M: Edgar E. Iglesias diff --git a/hw/bfin/bfin_boards.c b/hw/bfin/bfin_boards.c new file mode 100644 index 0000000000000..157f13281b477 --- /dev/null +++ b/hw/bfin/bfin_boards.c @@ -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) diff --git a/hw/bfin/bfin_devices.h b/hw/bfin/bfin_devices.h new file mode 100644 index 0000000000000..b7c8dd8e65166 --- /dev/null +++ b/hw/bfin/bfin_devices.h @@ -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] ? : "") + +#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 diff --git a/hw/bfin/bfin_dma.c b/hw/bfin/bfin_dma.c new file mode 100644 index 0000000000000..6d97b17f5c686 --- /dev/null +++ b/hw/bfin/bfin_dma.c @@ -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", "", "X_COUNT", "X_MODIFY", + "Y_COUNT", "Y_MODIFY", "CURR_DESC_PTR", "CURR_ADDR", "IRQ_STATUS", + "PERIPHERAL_MAP", "CURR_X_COUNT", "", "CURR_Y_COUNT", "", +}; + +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) diff --git a/hw/bfin/bfin_evt.c b/hw/bfin/bfin_evt.c new file mode 100644 index 0000000000000..033e698b4c5b4 --- /dev/null +++ b/hw/bfin/bfin_evt.c @@ -0,0 +1,94 @@ +/* + * Blackfin Event Vector Table (EVT) 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_EVT "bfin_evt" +#define BFIN_EVT(obj) OBJECT_CHECK(BfinEVTState, (obj), TYPE_BFIN_EVT) + +typedef struct BfinEVTState { + SysBusDevice parent_obj; + MemoryRegion iomem; + + /* Order after here is important -- matches hardware MMR layout. */ + bu32 evt[16]; +} BfinEVTState; +#define BfinMMRState BfinEVTState +#define mmr_base() offsetof(BfinMMRState, evt[0]) + +static const char * const mmr_names[0x2000 / 4] = +{ + "EVT0", "EVT1", "EVT2", "EVT3", "EVT4", "EVT5", "EVT6", "EVT7", "EVT8", + "EVT9", "EVT10", "EVT11", "EVT12", "EVT13", "EVT14", "EVT15", +}; + +static void bfin_evt_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinEVTState *s = opaque; + bu32 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_WRITE(); + + *valuep = value; +} + +static uint64_t bfin_evt_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinEVTState *s = opaque; + bu32 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_READ(); + + return *valuep; +} + +static const MemoryRegionOps bfin_evt_io_ops = { + .read = bfin_evt_io_read, + .write = bfin_evt_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void bfin_evt_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + BfinEVTState *s = BFIN_EVT(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_evt_io_ops, s, "evt", mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_evt_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bfin_evt_realize; +} + +static TypeInfo bfin_evt_info = { + .name = TYPE_BFIN_EVT, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinEVTState), + .class_init = bfin_evt_class_init, +}; + +static void bfin_evt_register_types(void) +{ + type_register_static(&bfin_evt_info); +} + +type_init(bfin_evt_register_types) diff --git a/hw/bfin/bfin_mmu.c b/hw/bfin/bfin_mmu.c new file mode 100644 index 0000000000000..2467d872da0e6 --- /dev/null +++ b/hw/bfin/bfin_mmu.c @@ -0,0 +1,133 @@ +/* + * Blackfin Memory Management Unit (MMU) 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_MMU "bfin_mmu" +#define BFIN_MMU(obj) OBJECT_CHECK(BfinMMUState, (obj), TYPE_BFIN_MMU) + +typedef struct BfinMMUState { + SysBusDevice parent_obj; + MemoryRegion iomem; + + /* Order after here is important -- matches hardware MMR layout. */ + bu32 sram_base_address; + + bu32 dmem_control, dcplb_fault_status, dcplb_fault_addr; + char _dpad0[0x100 - 0x0 - (4 * 4)]; + bu32 dcplb_addr[16]; + char _dpad1[0x200 - 0x100 - (4 * 16)]; + bu32 dcplb_data[16]; + char _dpad2[0x300 - 0x200 - (4 * 16)]; + bu32 dtest_command; + char _dpad3[0x400 - 0x300 - (4 * 1)]; + bu32 dtest_data[2]; + + char _dpad4[0x1000 - 0x400 - (4 * 2)]; + + bu32 idk; /* Filler MMR; hardware simply ignores. */ + bu32 imem_control, icplb_fault_status, icplb_fault_addr; + char _ipad0[0x100 - 0x0 - (4 * 4)]; + bu32 icplb_addr[16]; + char _ipad1[0x200 - 0x100 - (4 * 16)]; + bu32 icplb_data[16]; + char _ipad2[0x300 - 0x200 - (4 * 16)]; + bu32 itest_command; + char _ipad3[0x400 - 0x300 - (4 * 1)]; + bu32 itest_data[2]; +} BfinMMUState; +#define BfinMMRState BfinMMUState +#define mmr_base() offsetof(BfinMMRState, sram_base_address) + +static const char * const mmr_names[0x2000 / 4] = +{ + "SRAM_BASE_ADDRESS", "DMEM_CONTROL", "DCPLB_FAULT_STATUS", "DCPLB_FAULT_ADDR", + [mmr_idx (dcplb_addr[0])] = "DCPLB_ADDR0", + "DCPLB_ADDR1", "DCPLB_ADDR2", "DCPLB_ADDR3", "DCPLB_ADDR4", "DCPLB_ADDR5", + "DCPLB_ADDR6", "DCPLB_ADDR7", "DCPLB_ADDR8", "DCPLB_ADDR9", "DCPLB_ADDR10", + "DCPLB_ADDR11", "DCPLB_ADDR12", "DCPLB_ADDR13", "DCPLB_ADDR14", "DCPLB_ADDR15", + [mmr_idx (dcplb_data[0])] = "DCPLB_DATA0", + "DCPLB_DATA1", "DCPLB_DATA2", "DCPLB_DATA3", "DCPLB_DATA4", "DCPLB_DATA5", + "DCPLB_DATA6", "DCPLB_DATA7", "DCPLB_DATA8", "DCPLB_DATA9", "DCPLB_DATA10", + "DCPLB_DATA11", "DCPLB_DATA12", "DCPLB_DATA13", "DCPLB_DATA14", "DCPLB_DATA15", + [mmr_idx (dtest_command)] = "DTEST_COMMAND", + [mmr_idx (dtest_data[0])] = "DTEST_DATA0", "DTEST_DATA1", + [mmr_idx (imem_control)] = "IMEM_CONTROL", "ICPLB_FAULT_STATUS", "ICPLB_FAULT_ADDR", + [mmr_idx (icplb_addr[0])] = "ICPLB_ADDR0", + "ICPLB_ADDR1", "ICPLB_ADDR2", "ICPLB_ADDR3", "ICPLB_ADDR4", "ICPLB_ADDR5", + "ICPLB_ADDR6", "ICPLB_ADDR7", "ICPLB_ADDR8", "ICPLB_ADDR9", "ICPLB_ADDR10", + "ICPLB_ADDR11", "ICPLB_ADDR12", "ICPLB_ADDR13", "ICPLB_ADDR14", "ICPLB_ADDR15", + [mmr_idx (icplb_data[0])] = "ICPLB_DATA0", + "ICPLB_DATA1", "ICPLB_DATA2", "ICPLB_DATA3", "ICPLB_DATA4", "ICPLB_DATA5", + "ICPLB_DATA6", "ICPLB_DATA7", "ICPLB_DATA8", "ICPLB_DATA9", "ICPLB_DATA10", + "ICPLB_DATA11", "ICPLB_DATA12", "ICPLB_DATA13", "ICPLB_DATA14", "ICPLB_DATA15", + [mmr_idx (itest_command)] = "ITEST_COMMAND", + [mmr_idx (itest_data[0])] = "ITEST_DATA0", "ITEST_DATA1", +}; + +static void bfin_mmu_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinMMUState *s = opaque; + + HW_TRACE_WRITE(); +} + +static uint64_t bfin_mmu_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinMMUState *s = opaque; + + HW_TRACE_READ(); + + return 0; +} + +static const MemoryRegionOps bfin_mmu_io_ops = { + .read = bfin_mmu_io_read, + .write = bfin_mmu_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void bfin_mmu_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + BfinMMUState *s = BFIN_MMU(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_mmu_io_ops, s, "mmu", mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_mmu_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bfin_mmu_realize; +} + +static TypeInfo bfin_mmu_info = { + .name = "bfin_mmu", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinMMUState), + .class_init = bfin_mmu_class_init, +}; + +static void bfin_mmu_register_types(void) +{ + type_register_static(&bfin_mmu_info); +} + +type_init(bfin_mmu_register_types) diff --git a/hw/bfin/bfin_pll.c b/hw/bfin/bfin_pll.c new file mode 100644 index 0000000000000..ed35fc293c578 --- /dev/null +++ b/hw/bfin/bfin_pll.c @@ -0,0 +1,129 @@ +/* + * Blackfin Phase Lock Loop (PLL) 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_PLL "bfin_pll" +#define BFIN_PLL(obj) OBJECT_CHECK(BfinPLLState, (obj), TYPE_BFIN_PLL) + +typedef struct BfinPLLState { + SysBusDevice parent_obj; + MemoryRegion iomem; + + /* Order after here is important -- matches hardware MMR layout. */ + bu16 BFIN_MMR_16(pll_ctl); + bu16 BFIN_MMR_16(pll_div); + bu16 BFIN_MMR_16(vr_ctl); + bu16 BFIN_MMR_16(pll_stat); + bu16 BFIN_MMR_16(pll_lockcnt); + + /* XXX: Not really the best place for this ... */ + bu32 chipid; +} BfinPLLState; +#define BfinMMRState BfinPLLState +#define mmr_base() offsetof(BfinMMRState, pll_ctl) + +static const char * const mmr_names[] = +{ + "PLL_CTL", "PLL_DIV", "VR_CTL", "PLL_STAT", "PLL_LOCKCNT", "CHIPID", +}; + +static void bfin_pll_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinPLLState *s = opaque; + bu16 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_WRITE(); + + switch (addr) { + case mmr_offset(pll_stat): + case mmr_offset(chipid): + /* Discard writes. */ + break; + + default: + *valuep = value; + break; + } +} + +static uint64_t bfin_pll_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinPLLState *s = opaque; + bu16 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_READ(); + + switch (addr) { + case mmr_offset(chipid): + return s->chipid; + + default: + return *valuep; + } +} + +static const MemoryRegionOps bfin_pll_io_ops = { + .read = bfin_pll_io_read, + .write = bfin_pll_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 2, + .max_access_size = 4, + }, +}; + +static void pll_reset(DeviceState *d) +{ + BfinPLLState *s = BFIN_PLL(d); + + /* XXX: Depends on cpu/board. */ + s->pll_ctl = 0x1400; + s->pll_div = 0x0005; + s->vr_ctl = 0x40DB; + s->pll_stat = 0x00A2; + s->pll_lockcnt = 0x0200; + s->chipid = 0x1234; +} + +static void bfin_pll_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + BfinPLLState *s = BFIN_PLL(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_pll_io_ops, s, "pll", mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_pll_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bfin_pll_realize; + dc->reset = pll_reset; +} + +static TypeInfo bfin_pll_info = { + .name = "bfin_pll", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinPLLState), + .class_init = bfin_pll_class_init, +}; + +static void bfin_pll_register_types(void) +{ + type_register_static(&bfin_pll_info); +} + +type_init(bfin_pll_register_types) diff --git a/hw/bfin/bfin_sic.c b/hw/bfin/bfin_sic.c new file mode 100644 index 0000000000000..97496f5d5e583 --- /dev/null +++ b/hw/bfin/bfin_sic.c @@ -0,0 +1,123 @@ +/* + * Blackfin System Interrupt Controller (SIC) 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_SIC "bfin_sic" +#define BFIN_SIC(obj) OBJECT_CHECK(BfinSICState, (obj), TYPE_BFIN_SIC) + +typedef struct BfinSICState { + SysBusDevice parent_obj; + MemoryRegion iomem; + + /* Order after here is important -- matches hardware MMR layout. */ + bu16 BFIN_MMR_16(swrst); + bu16 BFIN_MMR_16(syscr); + bu16 BFIN_MMR_16(rvect); /* XXX: BF59x has a 32bit AUX_REVID here. */ + union { + struct { + bu32 imask0; + bu32 iar0, iar1, iar2, iar3; + bu32 isr0, iwr0; + bu32 _pad0[9]; + bu32 imask1; + bu32 iar4, iar5, iar6, iar7; + bu32 isr1, iwr1; + } bf52x; + struct { + bu32 imask; + bu32 iar0, iar1, iar2, iar3; + bu32 isr, iwr; + } bf537; + struct { + bu32 imask0, imask1, imask2; + bu32 isr0, isr1, isr2; + bu32 iwr0, iwr1, iwr2; + bu32 iar0, iar1, iar2, iar3; + bu32 iar4, iar5, iar6, iar7; + bu32 iar8, iar9, iar10, iar11; + } bf54x; + struct { + bu32 imask0, imask1; + bu32 iar0, iar1, iar2, iar3; + bu32 iar4, iar5, iar6, iar7; + bu32 isr0, isr1; + bu32 iwr0, iwr1; + } bf561; + }; +} BfinSICState; +#define BfinMMRState BfinSICState +#define mmr_base() offsetof(BfinMMRState, swrst) + +static const char * const mmr_names[] = +{ + "SWRST", "SYSCR", "SIC_RVECT", "SIC_IMASK", "SIC_IAR0", "SIC_IAR1", + "SIC_IAR2", "SIC_IAR3", "SIC_ISR", "SIC_IWR", +}; + +static void bfin_sic_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinSICState *s = opaque; + + HW_TRACE_WRITE(); +} + +static uint64_t bfin_sic_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinSICState *s = opaque; + + HW_TRACE_READ(); + + return 0; +} + +static const MemoryRegionOps bfin_sic_io_ops = { + .read = bfin_sic_io_read, + .write = bfin_sic_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 2, + .max_access_size = 4, + }, +}; + +static void bfin_sic_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + BfinSICState *s = BFIN_SIC(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_sic_io_ops, s, "sic", mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_sic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bfin_sic_realize; +} + +static TypeInfo bfin_sic_info = { + .name = "bfin_sic", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinSICState), + .class_init = bfin_sic_class_init, +}; + +static void bfin_sic_register_types(void) +{ + type_register_static(&bfin_sic_info); +} + +type_init(bfin_sic_register_types) diff --git a/hw/bfin/bfin_trace.c b/hw/bfin/bfin_trace.c new file mode 100644 index 0000000000000..f388ad5a9672c --- /dev/null +++ b/hw/bfin/bfin_trace.c @@ -0,0 +1,148 @@ +/* + * Blackfin Trace (TBUF) 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_TRACE "bfin_trace" +#define BFIN_TRACE(obj) OBJECT_CHECK(BfinTraceState, (obj), TYPE_BFIN_TRACE) + +/* Note: The circular buffering here might look a little buggy wrt mid-reads + and consuming the top entry, but this is simulating hardware behavior. + The hardware is simple, dumb, and fast. Don't write dumb Blackfin + software and you won't have a problem. */ + +/* The hardware is limited to 16 entries and defines TBUFCTL. Let's extend it ;). */ +#ifndef SIM_BFIN_TRACE_DEPTH +#define SIM_BFIN_TRACE_DEPTH 6 +#endif +#define SIM_BFIN_TRACE_LEN (1 << SIM_BFIN_TRACE_DEPTH) +#define SIM_BFIN_TRACE_LEN_MASK (SIM_BFIN_TRACE_LEN - 1) + +struct bfin_trace_entry { + bu32 src, dst; +}; + +typedef struct BfinTraceState { + SysBusDevice parent_obj; + MemoryRegion iomem; + + struct bfin_trace_entry buffer[SIM_BFIN_TRACE_LEN]; + int top, bottom; + bool mid; + + /* Order after here is important -- matches hardware MMR layout. */ + bu32 tbufctl, tbufstat; + char _pad[0x100 - 0x8]; + bu32 tbuf; +} BfinTraceState; +#define BfinMMRState BfinTraceState +#define mmr_base() offsetof(BfinMMRState, tbufctl) + +static const char * const mmr_names[] = +{ + "TBUFCTL", "TBUFSTAT", [mmr_offset (tbuf) / 4] = "TBUF", +}; + +/* Ugh, circular buffers. */ +#define TBUF_LEN(t) ((t)->top - (t)->bottom) +#define TBUF_IDX(i) ((i) & SIM_BFIN_TRACE_LEN_MASK) +/* TOP is the next slot to fill. */ +#define TBUF_TOP(t) (&(t)->buffer[TBUF_IDX((t)->top)]) +/* LAST is the latest valid slot. */ +#define TBUF_LAST(t) (&(t)->buffer[TBUF_IDX((t)->top - 1)]) +/* LAST_LAST is the second-to-last valid slot. */ +#define TBUF_LAST_LAST(t) (&(t)->buffer[TBUF_IDX((t)->top - 2)]) + +static void bfin_trace_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinTraceState *s = opaque; + + HW_TRACE_WRITE(); + + switch (addr) { + case mmr_offset(tbufctl): + s->tbufctl = value; + break; + case mmr_offset(tbufstat): + case mmr_offset(tbuf): + /* Discard writes to these. */ + break; + default: + /* TODO: Throw an invalid mmr exception. */ + break; + } +} + +static uint64_t bfin_trace_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinTraceState *s = opaque; + + HW_TRACE_READ(); + + switch (addr) { + case mmr_offset(tbufctl): + return s->tbufctl; + case mmr_offset(tbufstat): + /* Hardware is limited to 16 entries, so to stay compatible with + software, limit the value to 16. For software algorithms that + keep reading while (TBUFSTAT != 0), they'll get all of it. */ + return MIN(TBUF_LEN(s), 16); + case mmr_offset(tbuf): + /* XXX: Implement this. */ + return 0; + default: + /* TODO: Throw an invalid mmr exception. */ + return 0; + } +} + +static const MemoryRegionOps bfin_trace_io_ops = { + .read = bfin_trace_io_read, + .write = bfin_trace_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void bfin_trace_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + BfinTraceState *s = BFIN_TRACE(dev); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_trace_io_ops, s, "trace", mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_trace_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bfin_trace_realize; +} + +static TypeInfo bfin_trace_info = { + .name = "bfin_trace", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinTraceState), + .class_init = bfin_trace_class_init, +}; + +static void bfin_trace_register_types(void) +{ + type_register_static(&bfin_trace_info); +} + +type_init(bfin_trace_register_types) diff --git a/hw/bfin/bfin_uart.c b/hw/bfin/bfin_uart.c new file mode 100644 index 0000000000000..ca14385ca8d4e --- /dev/null +++ b/hw/bfin/bfin_uart.c @@ -0,0 +1,320 @@ +/* + * Blackfin Universal Asynchronous Receiver/Transmitter (UART) model. + * For "old style" UARTs on BF53x/etc... parts. + * + * Copyright 2007-2023 Mike Frysinger + * Copyright 2007-2011 Analog Devices, Inc. + * + * Licensed under the Lesser GPL 2 or later. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/bfin/bfin_uart.h" +#include "hw/char/serial.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/qdev-properties-system.h" +#include "hw/sysbus.h" +#include "migration/vmstate.h" +#include "chardev/char-fe.h" +#include "trace-root.h" +#include "bfin_uart.h" +#include "bfin_devices.h" + +#define TYPE_BFIN_UART "bfin_uart" +#define BFIN_UART(obj) OBJECT_CHECK(BfinUARTState, (obj), TYPE_BFIN_UART) + +typedef struct BfinUARTState { + SysBusDevice parent_obj; + CharBackend chr; + + MemoryRegion iomem; + + unsigned char saved_byte; + int saved_count; + + /* This is aliased to DLH. */ + bu16 ier; + /* These are aliased to DLL. */ + bu16 thr, rbr; + + /* Order after here is important -- matches hardware MMR layout. */ + bu16 BFIN_MMR_16(dll); + bu16 BFIN_MMR_16(dlh); + bu16 BFIN_MMR_16(iir); + bu16 BFIN_MMR_16(lcr); + bu16 BFIN_MMR_16(mcr); + bu16 BFIN_MMR_16(lsr); + bu16 BFIN_MMR_16(msr); + bu16 BFIN_MMR_16(scr); + bu16 _pad0[2]; + bu16 BFIN_MMR_16(gctl); +} BfinUARTState; +#define BfinMMRState BfinUARTState +#define mmr_base() offsetof(BfinMMRState, dll) + +static const char * const mmr_names[] = +{ + "UART_RBR/UART_THR", "UART_IER", "UART_IIR", "UART_LCR", "UART_MCR", + "UART_LSR", "UART_MSR", "UART_SCR", "", "UART_GCTL", +}; + +#undef mmr_name +static const char *mmr_name(BfinUARTState *uart, bu32 idx) +{ + if (uart->lcr & DLAB) + if (idx < 2) + return idx == 0 ? "UART_DLL" : "UART_DLH"; + return mmr_names[idx]; +} +#define mmr_name(off) mmr_name(s, (off) / 4) + +static bu16 +bfin_uart_write_byte(BfinUARTState *s, bu16 thr, bu16 mcr) +{ + unsigned char ch = thr; + + if (mcr & LOOP_ENA) { + /* XXX: This probably doesn't work exactly right with + external FIFOs ... */ + s->saved_byte = thr; + s->saved_count = 1; + } + + qemu_chr_fe_write(&s->chr, &ch, 1); + + return thr; +} + +static void bfin_uart_io_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + BfinUARTState *s = opaque; + bu16 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_WRITE(); + + switch (addr) { + case mmr_offset(dll): + if (s->lcr & DLAB) { + s->dll = value; + } else { + s->thr = bfin_uart_write_byte(s, value, s->mcr); + +/* + if (uart->ier & ETBEI) { + hw_port_event (me, DV_PORT_TX, 1); + } +*/ + } + break; + case mmr_offset(dlh): + if (s->lcr & DLAB) + s->dlh = value; + else + s->ier = value; + break; + case mmr_offset(iir): + case mmr_offset(lsr): + /* XXX: Writes are ignored ? */ + break; + case mmr_offset(lcr): + s->lcr = value; break; + case mmr_offset(mcr): + case mmr_offset(scr): + case mmr_offset(gctl): + *valuep = value; + break; + } +} + +static bu16 +bfin_uart_get_next_byte(BfinUARTState *s, bu16 rbr, bu16 mcr, bool *fresh) +{ + bool _fresh; + + /* NB: The "uart" here may only use interal state. */ + + if (!fresh) { + fresh = &_fresh; + } + + *fresh = false; + + if (s->saved_count > 0) { + *fresh = true; + rbr = s->saved_byte; + --s->saved_count; + } + + /* RX is disconnected, so only return local data. */ + if (!(mcr & LOOP_ENA)) { + qemu_chr_fe_accept_input(&s->chr); + } + + return rbr; +} + +static uint64_t bfin_uart_io_read(void *opaque, hwaddr addr, unsigned size) +{ + BfinUARTState *s = opaque; + bu16 *valuep = (void *)((uintptr_t)s + mmr_base() + addr); + + HW_TRACE_READ(); + + switch (addr) { + case mmr_offset(dll): + if (s->lcr & DLAB) { + return s->dll; + } else { + s->rbr = bfin_uart_get_next_byte(s, s->rbr, s->mcr, NULL); + return s->rbr; + } + case mmr_offset(dlh): + if (s->lcr & DLAB) { + return s->dlh; + } else { + return s->ier; + } + case mmr_offset(lsr): { + uint64_t ret; + /* XXX: Reads are destructive on most parts, but not all ... */ + s->lsr |= TEMT | THRE | (s->saved_count > 0 ? DR : 0); // bfin_uart_get_status (me); + ret = s->lsr; + s->lsr = 0; + return ret; + } + case mmr_offset(iir): + /* XXX: Reads are destructive ... */ + case mmr_offset(lcr): + case mmr_offset(mcr): + case mmr_offset(scr): + case mmr_offset(gctl): + return *valuep; + } + + return 0; +} + +static const MemoryRegionOps bfin_uart_io_ops = { + .read = bfin_uart_io_read, + .write = bfin_uart_io_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 2, + .max_access_size = 2, + }, +}; + +static Property bfin_uart_properties[] = { + DEFINE_PROP_CHR("chardev", BfinUARTState, chr), + DEFINE_PROP_END_OF_LIST(), +}; + +static void uart_rx(void *opaque, const uint8_t *buf, int size) +{ + BfinUARTState *s = opaque; + + if (s->lsr & DR) { + s->lsr |= OE; + } + + s->lsr |= DR; + s->saved_byte = *buf; + s->saved_count = 1; + +// uart_update_irq(s); +} + +static int uart_can_rx(void *opaque) +{ + BfinUARTState *s = opaque; + + return !(s->lsr & DR); +} + +static void uart_event(void *opaque, QEMUChrEvent event) +{ +} + +static void uart_reset(DeviceState *d) +{ + BfinUARTState *s = BFIN_UART(d); + + s->ier = 0; + s->thr = 0; + s->rbr = 0; + s->dll = 0x0001; + s->dlh = 0; + s->iir = 0x0001; + s->lcr = 0; + s->mcr = 0; + s->lsr = 0x0060; + s->msr = 0; + s->scr = 0; + s->gctl = 0; +} + +static void bfin_uart_instance_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + BfinUARTState *s = BFIN_UART(obj); + + memory_region_init_io(&s->iomem, OBJECT(s), &bfin_uart_io_ops, s, + TYPE_BFIN_UART, mmr_size()); + sysbus_init_mmio(sbd, &s->iomem); +} + +static void bfin_uart_realize(DeviceState *dev, Error **errp) +{ + BfinUARTState *s = BFIN_UART(dev); + + qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, + uart_event, NULL, s, NULL, true); +} + +static const VMStateDescription vmstate_bfin_uart = { + .name = "bfin-uart", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { +// VMSTATE_UINT32_ARRAY(regs, BfinUartState, R_MAX), + VMSTATE_END_OF_LIST() + } +}; + +static void bfin_uart_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = uart_reset; + dc->vmsd = &vmstate_bfin_uart; + device_class_set_props(dc, bfin_uart_properties); + dc->realize = bfin_uart_realize; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static TypeInfo bfin_uart_infos[] = { + { + .name = TYPE_BFIN_UART, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BfinUARTState), + .instance_init = bfin_uart_instance_init, + .class_init = bfin_uart_class_init, + }, +}; + +DEFINE_TYPES(bfin_uart_infos); + +void bfin_uart_init(hwaddr base, Chardev *chrdrv) +{ + DeviceState *dev; + + dev = qdev_new(TYPE_BFIN_UART); + if (chrdrv) { + qdev_prop_set_chr(dev, "chardev", chrdrv); + } + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); +} diff --git a/hw/bfin/bfin_uart.h b/hw/bfin/bfin_uart.h new file mode 100644 index 0000000000000..b2ae857f708e7 --- /dev/null +++ b/hw/bfin/bfin_uart.h @@ -0,0 +1,46 @@ +/* + * Blackfin Universal Asynchronous Receiver/Transmitter (UART) model. + * For "old style" UARTs on BF53x/etc... parts. + * + * Copyright 2007-2023 Mike Frysinger + * Copyright 2007-2011 Analog Devices, Inc. + * + * Licensed under the Lesser GPL 2 or later. + */ + +#ifndef DV_BFIN_UART_H +#define DV_BFIN_UART_H + +#include "exec/hwaddr.h" + +/* UART_LCR */ +#define DLAB (1 << 7) + +/* UART_LSR */ +#define TFI (1 << 7) +#define TEMT (1 << 6) +#define THRE (1 << 5) +#define BI (1 << 4) +#define FE (1 << 3) +#define PE (1 << 2) +#define OE (1 << 1) +#define DR (1 << 0) + +/* UART_IER */ +#define ERBFI (1 << 0) +#define ETBEI (1 << 1) +#define ELSI (1 << 2) + +/* UART_MCR */ +#define XOFF (1 << 0) +#define MRTS (1 << 1) +#define RFIT (1 << 2) +#define RFRT (1 << 3) +#define LOOP_ENA (1 << 4) +#define FCPOL (1 << 5) +#define ARTS (1 << 6) +#define ACTS (1 << 7) + +extern void bfin_uart_init(hwaddr base, Chardev *chrdrv); + +#endif diff --git a/hw/bfin/meson.build b/hw/bfin/meson.build new file mode 100644 index 0000000000000..1439869d40782 --- /dev/null +++ b/hw/bfin/meson.build @@ -0,0 +1,13 @@ +bfin_ss = ss.source_set() +bfin_ss.add(files( + 'bfin_boards.c', + 'bfin_dma.c', + 'bfin_evt.c', + 'bfin_mmu.c', + 'bfin_pll.c', + 'bfin_sic.c', + 'bfin_trace.c', + 'bfin_uart.c', +)) + +hw_arch += {'bfin': bfin_ss} diff --git a/hw/meson.build b/hw/meson.build index f01fac4617c99..aa93f8645862d 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -48,6 +48,7 @@ subdir('xenpv') subdir('alpha') subdir('arm') subdir('avr') +subdir('bfin') subdir('cris') subdir('hppa') subdir('i386') diff --git a/target/bfin/helper.c b/target/bfin/helper.c index 28b30b8154dfb..e2bf7df46b5d7 100644 --- a/target/bfin/helper.c +++ b/target/bfin/helper.c @@ -57,6 +57,14 @@ int cpu_handle_mmu_fault(CPUState *cs, target_ulong address, { int prot; + /* XXX: walk the CPLB tables here */ +#if 0 + static const char * const rw_map[] = { "read", "write", "exec", }; + + printf("%s: %5s @ " TARGET_FMT_lx " (mmu_idx=%i)\n", + __func__, rw_map[access_type], address, mmu_idx); +#endif + address &= TARGET_PAGE_MASK; prot = PAGE_BITS; tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); diff --git a/trace-events b/trace-events index dd318ed1af64d..d4dc6d3406a0c 100644 --- a/trace-events +++ b/trace-events @@ -30,6 +30,10 @@ breakpoint_insert(int cpu_index, uint64_t pc, int flags) "cpu=%d pc=0x%" PRIx64 breakpoint_remove(int cpu_index, uint64_t pc, int flags) "cpu=%d pc=0x%" PRIx64 " flags=0x%x" breakpoint_singlestep(int cpu_index, int enabled) "cpu=%d enable=%d" +# hw/bfin_*.c +bfin_reg_memory_read(uint32_t addr, const char *name, unsigned size) "read 0x%08x (%s) length %u" +bfin_reg_memory_write(uint32_t addr, const char *name, unsigned size, uint32_t value) "write 0x%08x (%s) length %u with 0x%x" + # dma-helpers.c dma_blk_io(void *dbs, void *bs, int64_t offset, bool to_dev) "dbs=%p bs=%p offset=%" PRId64 " to_dev=%d" dma_aio_cancel(void *dbs) "dbs=%p"