On Mon, Feb 19, 2018 at 11:34:25AM +0100, BALATON Zoltan wrote:
1;5002;0c> Add emulation of aCube Sam460ex board based on AMCC 460EX embedded 
SoC.
> This is not a complete implementation yet with a lot of components
> still missing but enough for the U-Boot firmware to start and to boot
> a Linux kernel or AROS.
> 
> Signed-off-by: Fran├žois Revol <re...@free.fr>
> Signed-off-by: BALATON Zoltan <bala...@eik.bme.hu>

I'm not thrilled with having a machine type that can't be used without
extracting a bootloader image from somewhere, but from the other
thread that's not easy to fix.

Since we have dtc in a submodule, there's really no reason we should
be including .dtb files as well as .dts files, we should build them
ourselves.  But fixing that isn't really in scope for this patch.

So, applied.

> ---
> v3:
> - Added device tree source and blob
> - Fixed clock frequency in device tree
>     
> v2:
> - Rebased to latest changes on master
> - Replaced printfs with error_report
> 
>  Makefile                           |   2 +-
>  default-configs/ppc-softmmu.mak    |   2 +
>  default-configs/ppcemb-softmmu.mak |   1 +
>  hw/ppc/Makefile.objs               |   3 +-
>  hw/ppc/sam460ex.c                  | 603 
> +++++++++++++++++++++++++++++++++++++
>  pc-bios/canyonlands.dtb            | Bin 0 -> 9779 bytes
>  pc-bios/canyonlands.dts            | 566 ++++++++++++++++++++++++++++++++++
>  7 files changed, 1175 insertions(+), 2 deletions(-)
>  create mode 100644 hw/ppc/sam460ex.c
>  create mode 100644 pc-bios/canyonlands.dtb
>  create mode 100644 pc-bios/canyonlands.dts
> 
> diff --git a/Makefile b/Makefile
> index 90e05ac..6434d6c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -656,7 +656,7 @@ efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
>  efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \
>  efi-e1000e.rom efi-vmxnet3.rom \
>  qemu-icon.bmp qemu_logo_no_text.svg \
> -bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
> +bamboo.dtb canyonlands.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
>  multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \
>  s390-ccw.img s390-netboot.img \
>  spapr-rtas.bin slof.bin skiboot.lid \
> diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
> index 76e29cf..4d7be45 100644
> --- a/default-configs/ppc-softmmu.mak
> +++ b/default-configs/ppc-softmmu.mak
> @@ -21,6 +21,8 @@ CONFIG_E500=y
>  CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM))
>  CONFIG_PLATFORM_BUS=y
>  CONFIG_ETSEC=y
> +# For Sam460ex
> +CONFIG_USB_EHCI_SYSBUS=y
>  CONFIG_SM501=y
>  CONFIG_IDE_SII3112=y
>  CONFIG_I2C=y
> diff --git a/default-configs/ppcemb-softmmu.mak 
> b/default-configs/ppcemb-softmmu.mak
> index bc5e1b3..67d18b2 100644
> --- a/default-configs/ppcemb-softmmu.mak
> +++ b/default-configs/ppcemb-softmmu.mak
> @@ -15,6 +15,7 @@ CONFIG_PTIMER=y
>  CONFIG_I8259=y
>  CONFIG_XILINX=y
>  CONFIG_XILINX_ETHLITE=y
> +CONFIG_USB_EHCI_SYSBUS=y
>  CONFIG_SM501=y
>  CONFIG_IDE_SII3112=y
>  CONFIG_I2C=y
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index bddc742..86d82a6 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -13,7 +13,8 @@ endif
>  obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
>  # PowerPC 4xx boards
>  obj-y += ppc4xx_devs.o ppc405_uc.o
> -obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o ppc440_bamboo.o 
> ppc440_pcix.o
> +obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o
> +obj-$(CONFIG_PPC4XX) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o sam460ex.o
>  # PReP
>  obj-$(CONFIG_PREP) += prep.o
>  obj-$(CONFIG_PREP) += prep_systemio.o
> diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
> new file mode 100644
> index 0000000..70b8e76
> --- /dev/null
> +++ b/hw/ppc/sam460ex.c
> @@ -0,0 +1,603 @@
> +/*
> + * QEMU aCube Sam460ex board emulation
> + *
> + * Copyright (c) 2012 Fran├žois Revol
> + * Copyright (c) 2016-2018 BALATON Zoltan
> + *
> + * This file is derived from hw/ppc440_bamboo.c,
> + * the copyright for that material belongs to the original owners.
> + *
> + * This work is licensed under the GNU GPL license version 2 or later.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "qemu/cutils.h"
> +#include "qemu/error-report.h"
> +#include "qapi/error.h"
> +#include "hw/hw.h"
> +#include "sysemu/blockdev.h"
> +#include "hw/boards.h"
> +#include "sysemu/kvm.h"
> +#include "kvm_ppc.h"
> +#include "sysemu/device_tree.h"
> +#include "sysemu/block-backend.h"
> +#include "hw/loader.h"
> +#include "elf.h"
> +#include "exec/address-spaces.h"
> +#include "exec/memory.h"
> +#include "hw/ppc/ppc440.h"
> +#include "hw/ppc/ppc405.h"
> +#include "hw/block/flash.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/qtest.h"
> +#include "hw/sysbus.h"
> +#include "hw/char/serial.h"
> +#include "hw/i2c/ppc4xx_i2c.h"
> +#include "hw/i2c/smbus.h"
> +#include "hw/usb/hcd-ehci.h"
> +
> +#define BINARY_DEVICE_TREE_FILE "canyonlands.dtb"
> +#define UBOOT_FILENAME "u-boot-sam460-20100605.bin"
> +/* to extract the official U-Boot bin from the updater: */
> +/* dd bs=1 skip=$(($(stat -c '%s' updater/updater-460) - 0x80000)) \
> +     if=updater/updater-460 of=u-boot-sam460-20100605.bin */
> +
> +/* from Sam460 U-Boot include/configs/Sam460ex.h */
> +#define FLASH_BASE             0xfff00000
> +#define FLASH_BASE_H           0x4
> +#define FLASH_SIZE             (1 << 20)
> +#define UBOOT_LOAD_BASE        0xfff80000
> +#define UBOOT_SIZE             0x00080000
> +#define UBOOT_ENTRY            0xfffffffc
> +
> +/* from U-Boot */
> +#define EPAPR_MAGIC           (0x45504150)
> +#define KERNEL_ADDR           0x1000000
> +#define FDT_ADDR              0x1800000
> +#define RAMDISK_ADDR          0x1900000
> +
> +/* Sam460ex IRQ MAP:
> +   IRQ0  = ETH_INT
> +   IRQ1  = FPGA_INT
> +   IRQ2  = PCI_INT (PCIA, PCIB, PCIC, PCIB)
> +   IRQ3  = FPGA_INT2
> +   IRQ11 = RTC_INT
> +   IRQ12 = SM502_INT
> +*/
> +
> +#define SDRAM_NR_BANKS 4
> +
> +/* FIXME: See u-boot.git 8ac41e, also fix in ppc440_uc.c */
> +static const unsigned int ppc460ex_sdram_bank_sizes[] = {
> +    1024 << 20, 512 << 20, 256 << 20, 128 << 20, 64 << 20, 32 << 20, 0
> +};
> +
> +struct boot_info {
> +    uint32_t dt_base;
> +    uint32_t dt_size;
> +    uint32_t entry;
> +};
> +
> +/*****************************************************************************/
> +/* SPD eeprom content from mips_malta.c */
> +
> +struct _eeprom24c0x_t {
> +  uint8_t tick;
> +  uint8_t address;
> +  uint8_t command;
> +  uint8_t ack;
> +  uint8_t scl;
> +  uint8_t sda;
> +  uint8_t data;
> +  uint8_t contents[256];
> +};
> +
> +typedef struct _eeprom24c0x_t eeprom24c0x_t;
> +
> +static eeprom24c0x_t spd_eeprom = {
> +    .contents = {
> +        /* 00000000: */ 0x80, 0x08, 0xFF, 0x0D, 0x0A, 0xFF, 0x40, 0x00,
> +        /* 00000008: */ 0x04, 0x75, 0x54, 0x00, 0x82, 0x08, 0x00, 0x01,
> +        /* 00000010: */ 0x8F, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,
> +        /* 00000018: */ 0x00, 0x00, 0x00, 0x14, 0x0F, 0x14, 0x2D, 0xFF,
> +        /* 00000020: */ 0x15, 0x08, 0x15, 0x08, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xD0,
> +        /* 00000040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +        /* 00000078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xF4,
> +    },
> +};
> +
> +static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size)
> +{
> +    enum { SDR = 0x4, DDR1 = 0x7, DDR2 = 0x8 } type;
> +    uint8_t *spd = spd_eeprom.contents;
> +    uint8_t nbanks = 0;
> +    uint16_t density = 0;
> +    int i;
> +
> +    /* work in terms of MB */
> +    ram_size >>= 20;
> +
> +    while ((ram_size >= 4) && (nbanks <= 2)) {
> +        int sz_log2 = MIN(31 - clz32(ram_size), 14);
> +        nbanks++;
> +        density |= 1 << (sz_log2 - 2);
> +        ram_size -= 1 << sz_log2;
> +    }
> +
> +    /* split to 2 banks if possible */
> +    if ((nbanks == 1) && (density > 1)) {
> +        nbanks++;
> +        density >>= 1;
> +    }
> +
> +    if (density & 0xff00) {
> +        density = (density & 0xe0) | ((density >> 8) & 0x1f);
> +        type = DDR2;
> +    } else if (!(density & 0x1f)) {
> +        type = DDR2;
> +    } else {
> +        type = SDR;
> +    }
> +
> +    if (ram_size) {
> +        warn_report("SPD cannot represent final " RAM_ADDR_FMT "MB"
> +                    " of SDRAM", ram_size);
> +    }
> +
> +    /* fill in SPD memory information */
> +    spd[2] = type;
> +    spd[5] = nbanks;
> +    spd[31] = density;
> +
> +    /* XXX: this is totally random */
> +    spd[9] = 0x10; /* CAS tcyc */
> +    spd[18] = 0x20; /* CAS bit */
> +    spd[23] = 0x10; /* CAS tcyc */
> +    spd[25] = 0x10; /* CAS tcyc */
> +
> +    /* checksum */
> +    spd[63] = 0;
> +    for (i = 0; i < 63; i++) {
> +        spd[63] += spd[i];
> +    }
> +
> +    /* copy for SMBUS */
> +    memcpy(eeprom, spd, sizeof(spd_eeprom.contents));
> +}
> +
> +static void generate_eeprom_serial(uint8_t *eeprom)
> +{
> +    int i, pos = 0;
> +    uint8_t mac[6] = { 0x00 };
> +    uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
> +
> +    /* version */
> +    eeprom[pos++] = 0x01;
> +
> +    /* count */
> +    eeprom[pos++] = 0x02;
> +
> +    /* MAC address */
> +    eeprom[pos++] = 0x01; /* MAC */
> +    eeprom[pos++] = 0x06; /* length */
> +    memcpy(&eeprom[pos], mac, sizeof(mac));
> +    pos += sizeof(mac);
> +
> +    /* serial number */
> +    eeprom[pos++] = 0x02; /* serial */
> +    eeprom[pos++] = 0x05; /* length */
> +    memcpy(&eeprom[pos], sn, sizeof(sn));
> +    pos += sizeof(sn);
> +
> +    /* checksum */
> +    eeprom[pos] = 0;
> +    for (i = 0; i < pos; i++) {
> +        eeprom[pos] += eeprom[i];
> +    }
> +}
> +
> +/*****************************************************************************/
> +
> +static int sam460ex_load_uboot(void)
> +{
> +    DriveInfo *dinfo;
> +    BlockBackend *blk = NULL;
> +    hwaddr base = FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32);
> +    long bios_size = FLASH_SIZE;
> +    int fl_sectors;
> +
> +    dinfo = drive_get(IF_PFLASH, 0, 0);
> +    if (dinfo) {
> +        blk = blk_by_legacy_dinfo(dinfo);
> +        bios_size = blk_getlength(blk);
> +    }
> +    fl_sectors = (bios_size + 65535) >> 16;
> +
> +    if (!pflash_cfi01_register(base, NULL, "sam460ex.flash", bios_size,
> +                               blk, (64 * 1024), fl_sectors,
> +                               1, 0x89, 0x18, 0x0000, 0x0, 1)) {
> +        error_report("qemu: Error registering flash memory.");
> +        /* XXX: return an error instead? */
> +        exit(1);
> +    }
> +
> +    if (!blk) {
> +        /*error_report("No flash image given with the 'pflash' parameter,"
> +                " using default u-boot image");*/
> +        base = UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32);
> +        rom_add_file_fixed(UBOOT_FILENAME, base, -1);
> +    }
> +
> +    return 0;
> +}
> +
> +static int sam460ex_load_device_tree(hwaddr addr,
> +                                     uint32_t ramsize,
> +                                     hwaddr initrd_base,
> +                                     hwaddr initrd_size,
> +                                     const char *kernel_cmdline)
> +{
> +    int ret = -1;
> +    uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) };
> +    char *filename;
> +    int fdt_size;
> +    void *fdt;
> +    uint32_t tb_freq = 50000000;
> +    uint32_t clock_freq = 50000000;
> +
> +    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
> +    if (!filename) {
> +        goto out;
> +    }
> +    fdt = load_device_tree(filename, &fdt_size);
> +    g_free(filename);
> +    if (fdt == NULL) {
> +        goto out;
> +    }
> +
> +    /* Manipulate device tree in memory. */
> +
> +    ret = qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
> +                               sizeof(mem_reg_property));
> +    if (ret < 0) {
> +        error_report("couldn't set /memory/reg");
> +    }
> +
> +    /* default FDT doesn't have a /chosen node... */
> +    qemu_fdt_add_subnode(fdt, "/chosen");
> +
> +    ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
> +                                    initrd_base);
> +    if (ret < 0) {
> +        error_report("couldn't set /chosen/linux,initrd-start");
> +    }
> +
> +    ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
> +                                    (initrd_base + initrd_size));
> +    if (ret < 0) {
> +        error_report("couldn't set /chosen/linux,initrd-end");
> +    }
> +
> +    ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
> +                                      kernel_cmdline);
> +    if (ret < 0) {
> +        error_report("couldn't set /chosen/bootargs");
> +    }
> +
> +    /* Copy data from the host device tree into the guest. Since the guest 
> can
> +     * directly access the timebase without host involvement, we must expose
> +     * the correct frequencies. */
> +    if (kvm_enabled()) {
> +        tb_freq = kvmppc_get_tbfreq();
> +        clock_freq = kvmppc_get_clockfreq();
> +    }
> +
> +    qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
> +                              clock_freq);
> +    qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
> +                              tb_freq);
> +
> +    rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
> +    g_free(fdt);
> +    ret = fdt_size;
> +
> +out:
> +
> +    return ret;
> +}
> +
> +/* Create reset TLB entries for BookE, mapping only the flash memory.  */
> +static void mmubooke_create_initial_mapping_uboot(CPUPPCState *env)
> +{
> +    ppcemb_tlb_t *tlb = &env->tlb.tlbe[0];
> +
> +    /* on reset the flash is mapped by a shadow TLB,
> +     * but since we don't implement them we need to use
> +     * the same values U-Boot will use to avoid a fault.
> +     */
> +    tlb->attr = 0;
> +    tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
> +    tlb->size = 0x10000000; /* up to 0xffffffff  */
> +    tlb->EPN = 0xf0000000 & TARGET_PAGE_MASK;
> +    tlb->RPN = (0xf0000000 & TARGET_PAGE_MASK) | 0x4;
> +    tlb->PID = 0;
> +}
> +
> +/* Create reset TLB entries for BookE, spanning the 32bit addr space.  */
> +static void mmubooke_create_initial_mapping(CPUPPCState *env,
> +                                     target_ulong va,
> +                                     hwaddr pa)
> +{
> +    ppcemb_tlb_t *tlb = &env->tlb.tlbe[0];
> +
> +    tlb->attr = 0;
> +    tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
> +    tlb->size = 1 << 31; /* up to 0x80000000  */
> +    tlb->EPN = va & TARGET_PAGE_MASK;
> +    tlb->RPN = pa & TARGET_PAGE_MASK;
> +    tlb->PID = 0;
> +}
> +
> +static void main_cpu_reset(void *opaque)
> +{
> +    PowerPCCPU *cpu = opaque;
> +    CPUPPCState *env = &cpu->env;
> +    struct boot_info *bi = env->load_info;
> +
> +    cpu_reset(CPU(cpu));
> +
> +    /* either we have a kernel to boot or we jump to U-Boot */
> +    if (bi->entry != UBOOT_ENTRY) {
> +        env->gpr[1] = (16 << 20) - 8;
> +        env->gpr[3] = FDT_ADDR;
> +        env->nip = bi->entry;
> +
> +        /* Create a mapping for the kernel.  */
> +        mmubooke_create_initial_mapping(env, 0, 0);
> +        env->gpr[6] = tswap32(EPAPR_MAGIC);
> +        env->gpr[7] = (16 << 20) - 8; /*bi->ima_size;*/
> +
> +    } else {
> +        env->nip = UBOOT_ENTRY;
> +        mmubooke_create_initial_mapping_uboot(env);
> +    }
> +}
> +
> +static void sam460ex_init(MachineState *machine)
> +{
> +    MemoryRegion *address_space_mem = get_system_memory();
> +    MemoryRegion *isa = g_new(MemoryRegion, 1);
> +    MemoryRegion *ram_memories = g_new(MemoryRegion, SDRAM_NR_BANKS);
> +    hwaddr ram_bases[SDRAM_NR_BANKS];
> +    hwaddr ram_sizes[SDRAM_NR_BANKS];
> +    MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1);
> +    qemu_irq *irqs, *uic[4];
> +    PCIBus *pci_bus;
> +    PowerPCCPU *cpu;
> +    CPUPPCState *env;
> +    PPC4xxI2CState *i2c[2];
> +    hwaddr entry = UBOOT_ENTRY;
> +    hwaddr loadaddr = 0;
> +    target_long initrd_size = 0;
> +    DeviceState *dev;
> +    SysBusDevice *sbdev;
> +    int success;
> +    int i;
> +    struct boot_info *boot_info;
> +    const size_t smbus_eeprom_size = 8 * 256;
> +    uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
> +
> +    cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
> +    env = &cpu->env;
> +    if (env->mmu_model != POWERPC_MMU_BOOKE) {
> +        error_report("Only MMU model BookE is supported by this machine.");
> +        exit(1);
> +    }
> +
> +#ifdef TARGET_PPCEMB
> +    if (!qtest_enabled()) {
> +        warn_report("qemu-system-ppcemb is deprecated, "
> +                    "please use qemu-system-ppc instead.");
> +    }
> +#endif
> +
> +    qemu_register_reset(main_cpu_reset, cpu);
> +    boot_info = g_malloc0(sizeof(*boot_info));
> +    env->load_info = boot_info;
> +
> +    ppc_booke_timers_init(cpu, 50000000, 0);
> +    ppc_dcr_init(env, NULL, NULL);
> +
> +    /* PLB arbitrer */
> +    ppc4xx_plb_init(env);
> +
> +    /* interrupt controllers */
> +    irqs = g_malloc0(sizeof(*irqs) * PPCUIC_OUTPUT_NB);
> +    irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq 
> *)env->irq_inputs)[PPC40x_INPUT_INT];
> +    irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq 
> *)env->irq_inputs)[PPC40x_INPUT_CINT];
> +    uic[0] = ppcuic_init(env, irqs, 0xc0, 0, 1);
> +    uic[1] = ppcuic_init(env, &uic[0][30], 0xd0, 0, 1);
> +    uic[2] = ppcuic_init(env, &uic[0][10], 0xe0, 0, 1);
> +    uic[3] = ppcuic_init(env, &uic[0][16], 0xf0, 0, 1);
> +
> +    /* SDRAM controller */
> +    memset(ram_bases, 0, sizeof(ram_bases));
> +    memset(ram_sizes, 0, sizeof(ram_sizes));
> +    /* put all RAM on first bank because board has one slot
> +     * and firmware only checks that */
> +    machine->ram_size = ppc4xx_sdram_adjust(machine->ram_size, 1,
> +                                   ram_memories, ram_bases, ram_sizes,
> +                                   ppc460ex_sdram_bank_sizes);
> +
> +    /* FIXME: does 460EX have ECC interrupts? */
> +    ppc440_sdram_init(env, SDRAM_NR_BANKS, ram_memories,
> +                      ram_bases, ram_sizes, 1);
> +
> +    /* generate SPD EEPROM data */
> +    for (i = 0; i < SDRAM_NR_BANKS; i++) {
> +        generate_eeprom_spd(&smbus_eeprom_buf[i * 256], ram_sizes[i]);
> +    }
> +    generate_eeprom_serial(&smbus_eeprom_buf[4 * 256]);
> +    generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
> +
> +    /* IIC controllers */
> +    dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600700, uic[0][2]);
> +    i2c[0] = PPC4xx_I2C(dev);
> +    object_property_set_bool(OBJECT(dev), true, "realized", NULL);
> +    smbus_eeprom_init(i2c[0]->bus, 8, smbus_eeprom_buf, smbus_eeprom_size);
> +    g_free(smbus_eeprom_buf);
> +
> +    dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600800, uic[0][3]);
> +    i2c[1] = PPC4xx_I2C(dev);
> +
> +    /* External bus controller */
> +    ppc405_ebc_init(env);
> +
> +    /* CPR */
> +    ppc4xx_cpr_init(env);
> +
> +    /* PLB to AHB bridge */
> +    ppc4xx_ahb_init(env);
> +
> +    /* System DCRs */
> +    ppc4xx_sdr_init(env);
> +
> +    /* MAL */
> +    ppc4xx_mal_init(env, 4, 16, &uic[2][3]);
> +
> +    /* 256K of L2 cache as memory */
> +    ppc4xx_l2sram_init(env);
> +    /* FIXME: remove this after fixing l2sram mapping in ppc440_uc.c? */
> +    memory_region_init_ram(l2cache_ram, NULL, "ppc440.l2cache_ram", 256 << 
> 10,
> +                           &error_abort);
> +    memory_region_add_subregion(address_space_mem, 0x400000000LL, 
> l2cache_ram);
> +
> +    /* USB */
> +    sysbus_create_simple(TYPE_PPC4xx_EHCI, 0x4bffd0400, uic[2][29]);
> +    dev = qdev_create(NULL, "sysbus-ohci");
> +    qdev_prop_set_string(dev, "masterbus", "usb-bus.0");
> +    qdev_prop_set_uint32(dev, "num-ports", 6);
> +    qdev_init_nofail(dev);
> +    sbdev = SYS_BUS_DEVICE(dev);
> +    sysbus_mmio_map(sbdev, 0, 0x4bffd0000);
> +    sysbus_connect_irq(sbdev, 0, uic[2][30]);
> +    usb_create_simple(usb_bus_find(-1), "usb-kbd");
> +    usb_create_simple(usb_bus_find(-1), "usb-mouse");
> +
> +    /* PCI bus */
> +    ppc460ex_pcie_init(env);
> +    /* FIXME: is this correct? */
> +    dev = sysbus_create_varargs("ppc440-pcix-host", 0xc0ec00000,
> +                                uic[1][0], uic[1][20], uic[1][21], 
> uic[1][22],
> +                                NULL);
> +    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
> +    if (!pci_bus) {
> +        error_report("couldn't create PCI controller!");
> +        exit(1);
> +    }
> +    memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(),
> +                             0, 0x10000);
> +    memory_region_add_subregion(get_system_memory(), 0xc08000000, isa);
> +
> +    /* PCI devices */
> +    pci_create_simple(pci_bus, PCI_DEVFN(6, 0), "sm501");
> +    /* SoC has a single SATA port but we don't emulate that yet
> +     * However, firmware and usual clients have driver for SiI311x
> +     * so add one for convenience by default */
> +    if (defaults_enabled()) {
> +        pci_create_simple(pci_bus, -1, "sii3112");
> +    }
> +
> +    /* SoC has 4 UARTs
> +     * but board has only one wired and two are present in fdt */
> +    if (serial_hds[0] != NULL) {
> +        serial_mm_init(address_space_mem, 0x4ef600300, 0, uic[1][1],
> +                       PPC_SERIAL_MM_BAUDBASE, serial_hds[0],
> +                       DEVICE_BIG_ENDIAN);
> +    }
> +    if (serial_hds[1] != NULL) {
> +        serial_mm_init(address_space_mem, 0x4ef600400, 0, uic[0][1],
> +                       PPC_SERIAL_MM_BAUDBASE, serial_hds[1],
> +                       DEVICE_BIG_ENDIAN);
> +    }
> +
> +    /* Load U-Boot image. */
> +    if (!machine->kernel_filename) {
> +        success = sam460ex_load_uboot();
> +        if (success < 0) {
> +            error_report("qemu: could not load firmware");
> +            exit(1);
> +        }
> +    }
> +
> +    /* Load kernel. */
> +    if (machine->kernel_filename) {
> +        success = load_uimage(machine->kernel_filename, &entry, &loadaddr,
> +                              NULL, NULL, NULL);
> +        if (success < 0) {
> +            uint64_t elf_entry, elf_lowaddr;
> +
> +            success = load_elf(machine->kernel_filename, NULL, NULL, 
> &elf_entry,
> +                               &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0);
> +            entry = elf_entry;
> +            loadaddr = elf_lowaddr;
> +        }
> +        /* XXX try again as binary */
> +        if (success < 0) {
> +            error_report("qemu: could not load kernel '%s'",
> +                    machine->kernel_filename);
> +            exit(1);
> +        }
> +    }
> +
> +    /* Load initrd. */
> +    if (machine->initrd_filename) {
> +        initrd_size = load_image_targphys(machine->initrd_filename,
> +                                          RAMDISK_ADDR,
> +                                          machine->ram_size - RAMDISK_ADDR);
> +        if (initrd_size < 0) {
> +            error_report("qemu: could not load ram disk '%s' at %x",
> +                    machine->initrd_filename, RAMDISK_ADDR);
> +            exit(1);
> +        }
> +    }
> +
> +    /* If we're loading a kernel directly, we must load the device tree too. 
> */
> +    if (machine->kernel_filename) {
> +        int dt_size;
> +
> +        dt_size = sam460ex_load_device_tree(FDT_ADDR, machine->ram_size,
> +                                    RAMDISK_ADDR, initrd_size,
> +                                    machine->kernel_cmdline);
> +        if (dt_size < 0) {
> +            error_report("couldn't load device tree");
> +            exit(1);
> +        }
> +
> +        boot_info->dt_base = FDT_ADDR;
> +        boot_info->dt_size = dt_size;
> +    }
> +
> +    boot_info->entry = entry;
> +}
> +
> +static void sam460ex_machine_init(MachineClass *mc)
> +{
> +    mc->desc = "aCube Sam460ex";
> +    mc->init = sam460ex_init;
> +    mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("460exb");
> +    mc->default_ram_size = 512 * M_BYTE;
> +}
> +
> +DEFINE_MACHINE("sam460ex", sam460ex_machine_init)
> diff --git a/pc-bios/canyonlands.dtb b/pc-bios/canyonlands.dtb
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..9dce3443ad9578a8a4bb92ba6970cb2ae54d1ec3
> GIT binary patch
> literal 9779
> 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
> 
> literal 0
> HcmV?d00001
> 
> diff --git a/pc-bios/canyonlands.dts b/pc-bios/canyonlands.dts
> new file mode 100644
> index 0000000..0d6ac92
> --- /dev/null
> +++ b/pc-bios/canyonlands.dts
> @@ -0,0 +1,566 @@
> +/*
> + * Device Tree Source for AMCC Canyonlands (460EX)
> + *
> + * Copyright 2008-2009 DENX Software Engineering, Stefan Roese <s...@denx.de>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without
> + * any warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +/ {
> +     #address-cells = <2>;
> +     #size-cells = <1>;
> +     model = "amcc,canyonlands";
> +     compatible = "amcc,canyonlands";
> +     dcr-parent = <&{/cpus/cpu@0}>;
> +
> +     aliases {
> +             ethernet0 = &EMAC0;
> +             ethernet1 = &EMAC1;
> +             serial0 = &UART0;
> +             serial1 = &UART1;
> +     };
> +
> +     cpus {
> +             #address-cells = <1>;
> +             #size-cells = <0>;
> +
> +             cpu@0 {
> +                     device_type = "cpu";
> +                     model = "PowerPC,460EX";
> +                     reg = <0x00000000>;
> +                     clock-frequency = <0>; /* Filled in by U-Boot */
> +                     timebase-frequency = <0>; /* Filled in by U-Boot */
> +                     i-cache-line-size = <32>;
> +                     d-cache-line-size = <32>;
> +                     i-cache-size = <32768>;
> +                     d-cache-size = <32768>;
> +                     dcr-controller;
> +                     dcr-access-method = "native";
> +                     next-level-cache = <&L2C0>;
> +             };
> +     };
> +
> +     memory {
> +             device_type = "memory";
> +             reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by 
> U-Boot */
> +     };
> +
> +     UIC0: interrupt-controller0 {
> +             compatible = "ibm,uic-460ex","ibm,uic";
> +             interrupt-controller;
> +             cell-index = <0>;
> +             dcr-reg = <0x0c0 0x009>;
> +             #address-cells = <0>;
> +             #size-cells = <0>;
> +             #interrupt-cells = <2>;
> +     };
> +
> +     UIC1: interrupt-controller1 {
> +             compatible = "ibm,uic-460ex","ibm,uic";
> +             interrupt-controller;
> +             cell-index = <1>;
> +             dcr-reg = <0x0d0 0x009>;
> +             #address-cells = <0>;
> +             #size-cells = <0>;
> +             #interrupt-cells = <2>;
> +             interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
> +             interrupt-parent = <&UIC0>;
> +     };
> +
> +     UIC2: interrupt-controller2 {
> +             compatible = "ibm,uic-460ex","ibm,uic";
> +             interrupt-controller;
> +             cell-index = <2>;
> +             dcr-reg = <0x0e0 0x009>;
> +             #address-cells = <0>;
> +             #size-cells = <0>;
> +             #interrupt-cells = <2>;
> +             interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
> +             interrupt-parent = <&UIC0>;
> +     };
> +
> +     UIC3: interrupt-controller3 {
> +             compatible = "ibm,uic-460ex","ibm,uic";
> +             interrupt-controller;
> +             cell-index = <3>;
> +             dcr-reg = <0x0f0 0x009>;
> +             #address-cells = <0>;
> +             #size-cells = <0>;
> +             #interrupt-cells = <2>;
> +             interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
> +             interrupt-parent = <&UIC0>;
> +     };
> +
> +     SDR0: sdr {
> +             compatible = "ibm,sdr-460ex";
> +             dcr-reg = <0x00e 0x002>;
> +     };
> +
> +     CPR0: cpr {
> +             compatible = "ibm,cpr-460ex";
> +             dcr-reg = <0x00c 0x002>;
> +     };
> +
> +     CPM0: cpm {
> +             compatible = "ibm,cpm";
> +             dcr-access-method = "native";
> +             dcr-reg = <0x160 0x003>;
> +             unused-units = <0x00000100>;
> +             idle-doze = <0x02000000>;
> +             standby = <0xfeff791d>;
> +     };
> +
> +     L2C0: l2c {
> +             compatible = "ibm,l2-cache-460ex", "ibm,l2-cache";
> +             dcr-reg = <0x020 0x008          /* Internal SRAM DCR's */
> +                        0x030 0x008>;        /* L2 cache DCR's */
> +             cache-line-size = <32>;         /* 32 bytes */
> +             cache-size = <262144>;          /* L2, 256K */
> +             interrupt-parent = <&UIC1>;
> +             interrupts = <11 1>;
> +     };
> +
> +     plb {
> +             compatible = "ibm,plb-460ex", "ibm,plb4";
> +             #address-cells = <2>;
> +             #size-cells = <1>;
> +             ranges;
> +             clock-frequency = <0>; /* Filled in by U-Boot */
> +
> +             SDRAM0: sdram {
> +                     compatible = "ibm,sdram-460ex", "ibm,sdram-405gp";
> +                     dcr-reg = <0x010 0x002>;
> +             };
> +
> +             CRYPTO: crypto@180000 {
> +                     compatible = "amcc,ppc460ex-crypto", 
> "amcc,ppc4xx-crypto";
> +                     reg = <4 0x00180000 0x80400>;
> +                     interrupt-parent = <&UIC0>;
> +                     interrupts = <0x1d 0x4>;
> +             };
> +
> +             HWRNG: hwrng@110000 {
> +                     compatible = "amcc,ppc460ex-rng", "ppc4xx-rng";
> +                     reg = <4 0x00110000 0x50>;
> +             };
> +
> +             MAL0: mcmal {
> +                     compatible = "ibm,mcmal-460ex", "ibm,mcmal2";
> +                     dcr-reg = <0x180 0x062>;
> +                     num-tx-chans = <2>;
> +                     num-rx-chans = <16>;
> +                     #address-cells = <0>;
> +                     #size-cells = <0>;
> +                     interrupt-parent = <&UIC2>;
> +                     interrupts = <  /*TXEOB*/ 0x6 0x4
> +                                     /*RXEOB*/ 0x7 0x4
> +                                     /*SERR*/  0x3 0x4
> +                                     /*TXDE*/  0x4 0x4
> +                                     /*RXDE*/  0x5 0x4>;
> +             };
> +
> +             USB0: ehci@bffd0400 {
> +                     compatible = "ibm,usb-ehci-460ex", "usb-ehci";
> +                     interrupt-parent = <&UIC2>;
> +                     interrupts = <0x1d 4>;
> +                     reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
> +             };
> +
> +             USB1: usb@bffd0000 {
> +                     compatible = "ohci-le";
> +                     reg = <4 0xbffd0000 0x60>;
> +                     interrupt-parent = <&UIC2>;
> +                     interrupts = <0x1e 4>;
> +             };
> +
> +             USBOTG0: usbotg@bff80000 {
> +                     compatible = "amcc,dwc-otg";
> +                     reg = <0x4 0xbff80000 0x10000>;
> +                     interrupt-parent = <&USBOTG0>;
> +                     #interrupt-cells = <1>;
> +                     #address-cells = <0>;
> +                     #size-cells = <0>;
> +                     interrupts = <0x0 0x1 0x2>;
> +                     interrupt-map = </* USB-OTG */ 0x0 &UIC2 0x1c 0x4
> +                                      /* HIGH-POWER */ 0x1 &UIC1 0x1a 0x8
> +                                      /* DMA */ 0x2 &UIC0 0xc 0x4>;
> +             };
> +
> +             AHBDMA: dma@bffd0800 {
> +                     compatible = "snps,dma-spear1340";
> +                     reg = <4 0xbffd0800 0x400>;
> +                     interrupt-parent = <&UIC3>;
> +                     interrupts = <0x5 0x4>;
> +                     #dma-cells = <3>;
> +             };
> +
> +             SATA0: sata@bffd1000 {
> +                     compatible = "amcc,sata-460ex";
> +                     reg = <4 0xbffd1000 0x800>;
> +                     interrupt-parent = <&UIC3>;
> +                     interrupts = <0x0 0x4>;
> +                     dmas = <&AHBDMA 0 1 0>;
> +                     dma-names = "sata-dma";
> +             };
> +
> +             POB0: opb {
> +                     compatible = "ibm,opb-460ex", "ibm,opb";
> +                     #address-cells = <1>;
> +                     #size-cells = <1>;
> +                     ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
> +                     clock-frequency = <0>; /* Filled in by U-Boot */
> +
> +                     EBC0: ebc {
> +                             compatible = "ibm,ebc-460ex", "ibm,ebc";
> +                             dcr-reg = <0x012 0x002>;
> +                             #address-cells = <2>;
> +                             #size-cells = <1>;
> +                             clock-frequency = <0>; /* Filled in by U-Boot */
> +                             /* ranges property is supplied by U-Boot */
> +                             interrupts = <0x6 0x4>;
> +                             interrupt-parent = <&UIC1>;
> +
> +                             nor_flash@0,0 {
> +                                     compatible = "amd,s29gl512n", 
> "cfi-flash";
> +                                     bank-width = <2>;
> +                                     reg = <0x00000000 0x00000000 
> 0x04000000>;
> +                                     #address-cells = <1>;
> +                                     #size-cells = <1>;
> +                                     partition@0 {
> +                                             label = "kernel";
> +                                             reg = <0x00000000 0x001e0000>;
> +                                     };
> +                                     partition@1e0000 {
> +                                             label = "dtb";
> +                                             reg = <0x001e0000 0x00020000>;
> +                                     };
> +                                     partition@200000 {
> +                                             label = "ramdisk";
> +                                             reg = <0x00200000 0x01400000>;
> +                                     };
> +                                     partition@1600000 {
> +                                             label = "jffs2";
> +                                             reg = <0x01600000 0x00400000>;
> +                                     };
> +                                     partition@1a00000 {
> +                                             label = "user";
> +                                             reg = <0x01a00000 0x02560000>;
> +                                     };
> +                                     partition@3f60000 {
> +                                             label = "env";
> +                                             reg = <0x03f60000 0x00040000>;
> +                                     };
> +                                     partition@3fa0000 {
> +                                             label = "u-boot";
> +                                             reg = <0x03fa0000 0x00060000>;
> +                                     };
> +                             };
> +
> +                             cpld@2,0 {
> +                                     compatible = "amcc,ppc460ex-bcsr";
> +                                     reg = <2 0x0 0x9>;
> +                             };
> +
> +                             ndfc@3,0 {
> +                                     compatible = "ibm,ndfc";
> +                                     reg = <0x00000003 0x00000000 
> 0x00002000>;
> +                                     ccr = <0x00001000>;
> +                                     bank-settings = <0x80002222>;
> +                                     #address-cells = <1>;
> +                                     #size-cells = <1>;
> +
> +                                     nand {
> +                                             #address-cells = <1>;
> +                                             #size-cells = <1>;
> +
> +                                             partition@0 {
> +                                                     label = "u-boot";
> +                                                     reg = <0x00000000 
> 0x00100000>;
> +                                             };
> +                                             partition@100000 {
> +                                                     label = "user";
> +                                                     reg = <0x00000000 
> 0x03f00000>;
> +                                             };
> +                                     };
> +                             };
> +                     };
> +
> +                     UART0: serial@ef600300 {
> +                             device_type = "serial";
> +                             compatible = "ns16550";
> +                             reg = <0xef600300 0x00000008>;
> +                             virtual-reg = <0xef600300>;
> +                             clock-frequency = <0>; /* Filled in by U-Boot */
> +                             current-speed = <0>; /* Filled in by U-Boot */
> +                             interrupt-parent = <&UIC1>;
> +                             interrupts = <0x1 0x4>;
> +                     };
> +
> +                     UART1: serial@ef600400 {
> +                             device_type = "serial";
> +                             compatible = "ns16550";
> +                             reg = <0xef600400 0x00000008>;
> +                             virtual-reg = <0xef600400>;
> +                             clock-frequency = <0>; /* Filled in by U-Boot */
> +                             current-speed = <0>; /* Filled in by U-Boot */
> +                             interrupt-parent = <&UIC0>;
> +                             interrupts = <0x1 0x4>;
> +                     };
> +
> +                     IIC0: i2c@ef600700 {
> +                             compatible = "ibm,iic-460ex", "ibm,iic";
> +                             reg = <0xef600700 0x00000014>;
> +                             interrupt-parent = <&UIC0>;
> +                             interrupts = <0x2 0x4>;
> +                             #address-cells = <1>;
> +                             #size-cells = <0>;
> +                                rtc@68 {
> +                                        compatible = "st,m41t80";
> +                                        reg = <0x68>;
> +                                     interrupt-parent = <&UIC2>;
> +                                     interrupts = <0x19 0x8>;
> +                                };
> +                                sttm@48 {
> +                                        compatible = "ad,ad7414";
> +                                        reg = <0x48>;
> +                                     interrupt-parent = <&UIC1>;
> +                                     interrupts = <0x14 0x8>;
> +                                };
> +                     };
> +
> +                     IIC1: i2c@ef600800 {
> +                             compatible = "ibm,iic-460ex", "ibm,iic";
> +                             reg = <0xef600800 0x00000014>;
> +                             interrupt-parent = <&UIC0>;
> +                             interrupts = <0x3 0x4>;
> +                     };
> +
> +                     GPIO0: gpio@ef600b00 {
> +                             compatible = "ibm,ppc4xx-gpio";
> +                             reg = <0xef600b00 0x00000048>;
> +                             gpio-controller;
> +                     };
> +
> +                     ZMII0: emac-zmii@ef600d00 {
> +                             compatible = "ibm,zmii-460ex", "ibm,zmii";
> +                             reg = <0xef600d00 0x0000000c>;
> +                     };
> +
> +                     RGMII0: emac-rgmii@ef601500 {
> +                             compatible = "ibm,rgmii-460ex", "ibm,rgmii";
> +                             reg = <0xef601500 0x00000008>;
> +                             has-mdio;
> +                     };
> +
> +                     TAH0: emac-tah@ef601350 {
> +                             compatible = "ibm,tah-460ex", "ibm,tah";
> +                             reg = <0xef601350 0x00000030>;
> +                     };
> +
> +                     TAH1: emac-tah@ef601450 {
> +                             compatible = "ibm,tah-460ex", "ibm,tah";
> +                             reg = <0xef601450 0x00000030>;
> +                     };
> +
> +                     EMAC0: ethernet@ef600e00 {
> +                             device_type = "network";
> +                             compatible = "ibm,emac-460ex", "ibm,emac4sync";
> +                             interrupt-parent = <&EMAC0>;
> +                             interrupts = <0x0 0x1>;
> +                             #interrupt-cells = <1>;
> +                             #address-cells = <0>;
> +                             #size-cells = <0>;
> +                             interrupt-map = </*Status*/ 0x0 &UIC2 0x10 0x4
> +                                              /*Wake*/   0x1 &UIC2 0x14 0x4>;
> +                             reg = <0xef600e00 0x000000c4>;
> +                             local-mac-address = [000000000000]; /* Filled 
> in by U-Boot */
> +                             mal-device = <&MAL0>;
> +                             mal-tx-channel = <0>;
> +                             mal-rx-channel = <0>;
> +                             cell-index = <0>;
> +                             max-frame-size = <9000>;
> +                             rx-fifo-size = <4096>;
> +                             tx-fifo-size = <2048>;
> +                             rx-fifo-size-gige = <16384>;
> +                             phy-mode = "rgmii";
> +                             phy-map = <0x00000000>;
> +                             rgmii-device = <&RGMII0>;
> +                             rgmii-channel = <0>;
> +                             tah-device = <&TAH0>;
> +                             tah-channel = <0>;
> +                             has-inverted-stacr-oc;
> +                             has-new-stacr-staopc;
> +                     };
> +
> +                     EMAC1: ethernet@ef600f00 {
> +                             device_type = "network";
> +                             compatible = "ibm,emac-460ex", "ibm,emac4sync";
> +                             interrupt-parent = <&EMAC1>;
> +                             interrupts = <0x0 0x1>;
> +                             #interrupt-cells = <1>;
> +                             #address-cells = <0>;
> +                             #size-cells = <0>;
> +                             interrupt-map = </*Status*/ 0x0 &UIC2 0x11 0x4
> +                                              /*Wake*/   0x1 &UIC2 0x15 0x4>;
> +                             reg = <0xef600f00 0x000000c4>;
> +                             local-mac-address = [000000000000]; /* Filled 
> in by U-Boot */
> +                             mal-device = <&MAL0>;
> +                             mal-tx-channel = <1>;
> +                             mal-rx-channel = <8>;
> +                             cell-index = <1>;
> +                             max-frame-size = <9000>;
> +                             rx-fifo-size = <4096>;
> +                             tx-fifo-size = <2048>;
> +                             rx-fifo-size-gige = <16384>;
> +                             phy-mode = "rgmii";
> +                             phy-map = <0x00000000>;
> +                             rgmii-device = <&RGMII0>;
> +                             rgmii-channel = <1>;
> +                             tah-device = <&TAH1>;
> +                             tah-channel = <1>;
> +                             has-inverted-stacr-oc;
> +                             has-new-stacr-staopc;
> +                             mdio-device = <&EMAC0>;
> +                     };
> +             };
> +
> +             PCIX0: pci@c0ec00000 {
> +                     device_type = "pci";
> +                     #interrupt-cells = <1>;
> +                     #size-cells = <2>;
> +                     #address-cells = <3>;
> +                     compatible = "ibm,plb-pcix-460ex", "ibm,plb-pcix";
> +                     primary;
> +                     large-inbound-windows;
> +                     enable-msi-hole;
> +                     reg = <0x0000000c 0x0ec00000   0x00000008       /* 
> Config space access */
> +                            0x00000000 0x00000000 0x00000000         /* no 
> IACK cycles */
> +                            0x0000000c 0x0ed00000   0x00000004   /* Special 
> cycles */
> +                            0x0000000c 0x0ec80000 0x00000100 /* Internal 
> registers */
> +                            0x0000000c 0x0ec80100  0x000000fc>;      /* 
> Internal messaging registers */
> +
> +                     /* Outbound ranges, one memory and one IO,
> +                      * later cannot be changed
> +                      */
> +                     ranges = <0x02000000 0x00000000 0x80000000 0x0000000d 
> 0x80000000 0x00000000 0x80000000
> +                               0x02000000 0x00000000 0x00000000 0x0000000c 
> 0x0ee00000 0x00000000 0x00100000
> +                               0x01000000 0x00000000 0x00000000 0x0000000c 
> 0x08000000 0x00000000 0x00010000>;
> +
> +                     /* Inbound 2GB range starting at 0 */
> +                     dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 
> 0x80000000>;
> +
> +                     /* This drives busses 0 to 0x3f */
> +                     bus-range = <0x0 0x3f>;
> +
> +                     /* All PCI interrupts are routed to ext IRQ 2 -> UIC1-0 
> */
> +                     interrupt-map-mask = <0x0 0x0 0x0 0x0>;
> +                     interrupt-map = < 0x0 0x0 0x0 0x0 &UIC1 0x0 0x8 >;
> +             };
> +
> +             PCIE0: pciex@d00000000 {
> +                     device_type = "pci";
> +                     #interrupt-cells = <1>;
> +                     #size-cells = <2>;
> +                     #address-cells = <3>;
> +                     compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";
> +                     primary;
> +                     port = <0x0>; /* port number */
> +                     reg = <0x0000000d 0x00000000 0x20000000 /* Config space 
> access */
> +                            0x0000000c 0x08010000 0x00001000>;       /* 
> Registers */
> +                     dcr-reg = <0x100 0x020>;
> +                     sdr-base = <0x300>;
> +
> +                     /* Outbound ranges, one memory and one IO,
> +                      * later cannot be changed
> +                      */
> +                     ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 
> 0x00000000 0x00000000 0x80000000
> +                               0x02000000 0x00000000 0x00000000 0x0000000f 
> 0x00000000 0x00000000 0x00100000
> +                               0x01000000 0x00000000 0x00000000 0x0000000f 
> 0x80000000 0x00000000 0x00010000>;
> +
> +                     /* Inbound 2GB range starting at 0 */
> +                     dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 
> 0x80000000>;
> +
> +                     /* This drives busses 40 to 0x7f */
> +                     bus-range = <0x40 0x7f>;
> +
> +                     /* Legacy interrupts (note the weird polarity, the 
> bridge seems
> +                      * to invert PCIe legacy interrupts).
> +                      * We are de-swizzling here because the numbers are 
> actually for
> +                      * port of the root complex virtual P2P bridge. But I 
> want
> +                      * to avoid putting a node for it in the tree, so the 
> numbers
> +                      * below are basically de-swizzled numbers.
> +                      * The real slot is on idsel 0, so the swizzling is 1:1
> +                      */
> +                     interrupt-map-mask = <0x0 0x0 0x0 0x7>;
> +                     interrupt-map = <
> +                             0x0 0x0 0x0 0x1 &UIC3 0xc 0x4 /* swizzled int A 
> */
> +                             0x0 0x0 0x0 0x2 &UIC3 0xd 0x4 /* swizzled int B 
> */
> +                             0x0 0x0 0x0 0x3 &UIC3 0xe 0x4 /* swizzled int C 
> */
> +                             0x0 0x0 0x0 0x4 &UIC3 0xf 0x4 /* swizzled int D 
> */>;
> +             };
> +
> +             PCIE1: pciex@d20000000 {
> +                     device_type = "pci";
> +                     #interrupt-cells = <1>;
> +                     #size-cells = <2>;
> +                     #address-cells = <3>;
> +                     compatible = "ibm,plb-pciex-460ex", "ibm,plb-pciex";
> +                     primary;
> +                     port = <0x1>; /* port number */
> +                     reg = <0x0000000d 0x20000000 0x20000000 /* Config space 
> access */
> +                            0x0000000c 0x08011000 0x00001000>;       /* 
> Registers */
> +                     dcr-reg = <0x120 0x020>;
> +                     sdr-base = <0x340>;
> +
> +                     /* Outbound ranges, one memory and one IO,
> +                      * later cannot be changed
> +                      */
> +                     ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 
> 0x80000000 0x00000000 0x80000000
> +                               0x02000000 0x00000000 0x00000000 0x0000000f 
> 0x00100000 0x00000000 0x00100000
> +                               0x01000000 0x00000000 0x00000000 0x0000000f 
> 0x80010000 0x00000000 0x00010000>;
> +
> +                     /* Inbound 2GB range starting at 0 */
> +                     dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 
> 0x80000000>;
> +
> +                     /* This drives busses 80 to 0xbf */
> +                     bus-range = <0x80 0xbf>;
> +
> +                     /* Legacy interrupts (note the weird polarity, the 
> bridge seems
> +                      * to invert PCIe legacy interrupts).
> +                      * We are de-swizzling here because the numbers are 
> actually for
> +                      * port of the root complex virtual P2P bridge. But I 
> want
> +                      * to avoid putting a node for it in the tree, so the 
> numbers
> +                      * below are basically de-swizzled numbers.
> +                      * The real slot is on idsel 0, so the swizzling is 1:1
> +                      */
> +                     interrupt-map-mask = <0x0 0x0 0x0 0x7>;
> +                     interrupt-map = <
> +                             0x0 0x0 0x0 0x1 &UIC3 0x10 0x4 /* swizzled int 
> A */
> +                             0x0 0x0 0x0 0x2 &UIC3 0x11 0x4 /* swizzled int 
> B */
> +                             0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int 
> C */
> +                             0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int 
> D */>;
> +             };
> +
> +             MSI: ppc4xx-msi@C10000000 {
> +                     compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
> +                     reg = < 0xC 0x10000000 0x100>;
> +                     sdr-base = <0x36C>;
> +                     msi-data = <0x00000000>;
> +                     msi-mask = <0x44440000>;
> +                     interrupt-count = <3>;
> +                     interrupts = <0 1 2 3>;
> +                     interrupt-parent = <&UIC3>;
> +                     #interrupt-cells = <1>;
> +                     #address-cells = <0>;
> +                     #size-cells = <0>;
> +                     interrupt-map = <0 &UIC3 0x18 1
> +                                     1 &UIC3 0x19 1
> +                                     2 &UIC3 0x1A 1
> +                                     3 &UIC3 0x1B 1>;
> +             };
> +     };
> +};

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature

Reply via email to