|  | 
|  | 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) | 
0 commit comments