From patchwork Sun Feb 21 09:55:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiko Jehmlich X-Patchwork-Id: 1443030 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.helo=coreboot.org (client-ip=78.46.105.101; helo=coreboot.org; envelope-from=flashrom-bounces@flashrom.org; receiver=) Received: from coreboot.org (coreboot.org [78.46.105.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DkdHw1C2Xz9sVV for ; Mon, 22 Feb 2021 21:11:22 +1100 (AEDT) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 65FC714E11C2; Mon, 22 Feb 2021 10:11:13 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id B9EA314E11AD for ; Sun, 21 Feb 2021 09:55:13 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by rubidium.selfhost.de (Postfix) with ESMTPSA id E5E9A403EC66D for ; Sun, 21 Feb 2021 10:55:12 +0100 (CET) To: flashrom@flashrom.org From: Heiko Jehmlich Message-ID: <34bfdb5d-6670-69b6-1593-1c9ba1112cfb@jecons.de> Date: Sun, 21 Feb 2021 10:55:12 +0100 MIME-Version: 1.0 Content-Language: en-US X-PPP-Message-ID: <20210221095513.11065.29011@rubidium.selfhost.de> X-PPP-Vhost: jecons.de X-MailFrom: hje@jecons.de X-Mailman-Rule-Hits: emergency X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved Message-ID-Hash: HCKT4YTQEP2B5XBWCMJ4FQHAJDLGJVSZ X-Message-ID-Hash: HCKT4YTQEP2B5XBWCMJ4FQHAJDLGJVSZ X-Mailman-Approved-At: Mon, 22 Feb 2021 10:11:02 +0000 X-Mailman-Version: 3.3.4b1 Precedence: list Subject: [flashrom] DEC Tulip programmer List-Id: flashrom discussion and development mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=flashrom-bounces@flashrom.org X-Spamd-Bar: / Hi flashrom guys, based on the 3COM NIC programmer I created a new one for DEC Tulip Cards. The IC socket on these cards is 28pin so it supports only chips up to 64kB. I tested reading with several 27C256 chips (old 386er BIOSes). Therefore I also created two dumb EPROMS in flashchips. Also I added the ST M29F010B chip, tested on a 3COM NIC. Best regards Heiko Jehmlich +    return 0; +} + + +#else +#error PCI port I/O access is not supported on this architecture yet. +#endif diff --git a/Makefile b/Makefile index 6d37d55..af19d25 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_GFXNVIDIA), yes)  UNSUPPORTED_FEATURES += CONFIG_GFXNVIDIA=yes  else @@ -514,6 +519,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_NICREALTEK), yes)  UNSUPPORTED_FEATURES += CONFIG_NICREALTEK=yes  else @@ -570,6 +580,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_GFXNVIDIA), yes)  UNSUPPORTED_FEATURES += CONFIG_GFXNVIDIA=yes  else @@ -699,6 +714,9 @@ CONFIG_PONY_SPI ?= yes  # Always enable 3Com NICs for now.  CONFIG_NIC3COM ?= yes +# Always enable DECchip NICs for now. +CONFIG_NICTULIP ?= yes +  # Enable NVIDIA graphics cards. Note: write and erase do not work properly.  CONFIG_GFXNVIDIA ?= yes @@ -826,6 +844,7 @@ endif  ifeq ($(CONFIG_ENABLE_LIBPCI_PROGRAMMERS), no)  override CONFIG_INTERNAL = no  override CONFIG_NIC3COM = no +override CONFIG_NICTULIP = no  override CONFIG_GFXNVIDIA = no  override CONFIG_SATASII = no  override CONFIG_ATAHPT = no @@ -954,6 +973,12 @@ PROGRAMMER_OBJS += nic3com.o  NEED_LIBPCI += CONFIG_NIC3COM  endif +ifeq ($(CONFIG_NICTULIP), yes) +FEATURE_CFLAGS += -D'CONFIG_NICTULIP=1' +PROGRAMMER_OBJS += nictulip.o +NEED_LIBPCI += CONFIG_NICTULIP +endif +  ifeq ($(CONFIG_GFXNVIDIA), yes)  FEATURE_CFLAGS += -D'CONFIG_GFXNVIDIA=1'  PROGRAMMER_OBJS += gfxnvidia.o diff --git a/flashchips.c b/flashchips.c index 6d94a12..1491cdc 100644 --- a/flashchips.c +++ b/flashchips.c @@ -57,6 +57,38 @@ const struct flashchip flashchips[] = {       */      { +        .vendor        = "EPROM", +        .name        = "27C256", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = GENERIC_MANUF_ID, +        .model_id    = 0x00, +        .total_size    = 32, +        .page_size    = 0, /* unused */ +        .feature_bits    = 0, +        .tested        = {.probe = BAD, .read = OK, .erase = BAD, .write = BAD}, +        .probe        = NULL, +        .write        = NULL, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    { +        .vendor        = "EPROM", +        .name        = "27C512", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = GENERIC_MANUF_ID, +        .model_id    = 0x00, +        .total_size    = 64, +        .page_size    = 0, /* unused */ +        .feature_bits    = 0, +        .tested        = {.probe = BAD, .read = OK, .erase = BAD, .write = BAD}, +        .probe        = NULL, +        .write        = NULL, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    {          .vendor        = "AMD",          .name        = "Am29F002(N)BB",          .bustype    = BUS_PARALLEL, @@ -14764,6 +14796,33 @@ const struct flashchip flashchips[] = {      {          .vendor        = "ST", +        .name        = "M29F010B", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = ST_ID, +        .model_id    = ST_M29F010B, +        .total_size    = 128, +        .page_size    = 16 * 1024, +        .feature_bits    = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, +        .tested        = TEST_OK_PREW, +        .probe        = probe_jedec, +        .probe_timing    = TIMING_ZERO, /* datasheet specifies no timing */ +        .block_erasers    = +        { +            { +                .eraseblocks = { {16 * 1024, 8} }, +                .block_erase = erase_sector_jedec, +            }, { +                .eraseblocks = { {128 * 1024, 1} }, +                .block_erase = erase_chip_block_jedec, +            } +        }, +        .write        = write_jedec_1, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    { +        .vendor        = "ST",          .name        = "M29F040B",          .bustype    = BUS_PARALLEL,          .manufacture_id    = ST_ID, diff --git a/flashchips.h b/flashchips.h index a85fa6a..a3935ce 100644 --- a/flashchips.h +++ b/flashchips.h @@ -838,6 +838,7 @@  #define ST_M50LPW116        0x30  #define ST_M29F002B        0x34    /* Same as M29F002BB */  #define ST_M29F002T        0xB0    /* Same as M29F002BT/M29F002NT/M29F002BNT */ +#define ST_M29F010B        0x20    /* Same as M29F010 */  #define ST_M29F040B        0xE2    /* Same as M29F040 */  #define ST_M29F080        0xF1  #define ST_M29F200BT        0xD3 diff --git a/flashrom.c b/flashrom.c index c89abad..267d0ef 100644 --- a/flashrom.c +++ b/flashrom.c @@ -108,6 +108,18 @@ const struct programmer_entry programmer_table[] = {      },  #endif +#if CONFIG_NICTULIP == 1 +    { +        .name            = "nictulip", +        .type            = PCI, +        .devs.dev        = nics_tulip, +        .init            = nictulip_init, +        .map_flash_region    = fallback_map, +        .unmap_flash_region    = fallback_unmap, +        .delay            = internal_delay, +    }, +#endif +  #if CONFIG_NICREALTEK == 1      {          /* This programmer works for Realtek RTL8139 and SMC 1211. */ diff --git a/programmer.h b/programmer.h index 29a100b..a9608e0 100644 --- a/programmer.h +++ b/programmer.h @@ -37,6 +37,9 @@ enum programmer {  #if CONFIG_NIC3COM == 1      PROGRAMMER_NIC3COM,  #endif +#if CONFIG_NICTULIP == 1 +    PROGRAMMER_NICTULIP, +#endif  #if CONFIG_NICREALTEK == 1      PROGRAMMER_NICREALTEK,  #endif @@ -410,6 +413,12 @@ int nic3com_init(void);  extern const struct dev_entry nics_3com[];  #endif +/* nictulip.c */ +#if CONFIG_NICTULIP == 1 +int nictulip_init(void); +extern const struct dev_entry nics_tulip[]; +#endif +  /* gfxnvidia.c */  #if CONFIG_GFXNVIDIA == 1  int gfxnvidia_init(void); diff --git a/Makefile b/Makefile index 6d37d55..af19d25 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_GFXNVIDIA), yes)  UNSUPPORTED_FEATURES += CONFIG_GFXNVIDIA=yes  else @@ -514,6 +519,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_NICREALTEK), yes)  UNSUPPORTED_FEATURES += CONFIG_NICREALTEK=yes  else @@ -570,6 +580,11 @@ UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes  else  override CONFIG_NIC3COM = no  endif +ifeq ($(CONFIG_NICTULIP), yes) +UNSUPPORTED_FEATURES += CONFIG_NICTULIP=yes +else +override CONFIG_NICTULIP = no +endif  ifeq ($(CONFIG_GFXNVIDIA), yes)  UNSUPPORTED_FEATURES += CONFIG_GFXNVIDIA=yes  else @@ -699,6 +714,9 @@ CONFIG_PONY_SPI ?= yes  # Always enable 3Com NICs for now.  CONFIG_NIC3COM ?= yes +# Always enable DECchip NICs for now. +CONFIG_NICTULIP ?= yes +  # Enable NVIDIA graphics cards. Note: write and erase do not work properly.  CONFIG_GFXNVIDIA ?= yes @@ -826,6 +844,7 @@ endif  ifeq ($(CONFIG_ENABLE_LIBPCI_PROGRAMMERS), no)  override CONFIG_INTERNAL = no  override CONFIG_NIC3COM = no +override CONFIG_NICTULIP = no  override CONFIG_GFXNVIDIA = no  override CONFIG_SATASII = no  override CONFIG_ATAHPT = no @@ -954,6 +973,12 @@ PROGRAMMER_OBJS += nic3com.o  NEED_LIBPCI += CONFIG_NIC3COM  endif +ifeq ($(CONFIG_NICTULIP), yes) +FEATURE_CFLAGS += -D'CONFIG_NICTULIP=1' +PROGRAMMER_OBJS += nictulip.o +NEED_LIBPCI += CONFIG_NICTULIP +endif +  ifeq ($(CONFIG_GFXNVIDIA), yes)  FEATURE_CFLAGS += -D'CONFIG_GFXNVIDIA=1'  PROGRAMMER_OBJS += gfxnvidia.o diff --git a/flashchips.c b/flashchips.c index 6d94a12..1491cdc 100644 --- a/flashchips.c +++ b/flashchips.c @@ -57,6 +57,38 @@ const struct flashchip flashchips[] = {       */      { +        .vendor        = "EPROM", +        .name        = "27C256", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = GENERIC_MANUF_ID, +        .model_id    = 0x00, +        .total_size    = 32, +        .page_size    = 0, /* unused */ +        .feature_bits    = 0, +        .tested        = {.probe = BAD, .read = OK, .erase = BAD, .write = BAD}, +        .probe        = NULL, +        .write        = NULL, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    { +        .vendor        = "EPROM", +        .name        = "27C512", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = GENERIC_MANUF_ID, +        .model_id    = 0x00, +        .total_size    = 64, +        .page_size    = 0, /* unused */ +        .feature_bits    = 0, +        .tested        = {.probe = BAD, .read = OK, .erase = BAD, .write = BAD}, +        .probe        = NULL, +        .write        = NULL, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    {          .vendor        = "AMD",          .name        = "Am29F002(N)BB",          .bustype    = BUS_PARALLEL, @@ -14764,6 +14796,33 @@ const struct flashchip flashchips[] = {      {          .vendor        = "ST", +        .name        = "M29F010B", +        .bustype    = BUS_PARALLEL, +        .manufacture_id    = ST_ID, +        .model_id    = ST_M29F010B, +        .total_size    = 128, +        .page_size    = 16 * 1024, +        .feature_bits    = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET, +        .tested        = TEST_OK_PREW, +        .probe        = probe_jedec, +        .probe_timing    = TIMING_ZERO, /* datasheet specifies no timing */ +        .block_erasers    = +        { +            { +                .eraseblocks = { {16 * 1024, 8} }, +                .block_erase = erase_sector_jedec, +            }, { +                .eraseblocks = { {128 * 1024, 1} }, +                .block_erase = erase_chip_block_jedec, +            } +        }, +        .write        = write_jedec_1, +        .read        = read_memmapped, +        .voltage    = {4500, 5500}, +    }, + +    { +        .vendor        = "ST",          .name        = "M29F040B",          .bustype    = BUS_PARALLEL,          .manufacture_id    = ST_ID, diff --git a/flashchips.h b/flashchips.h index a85fa6a..a3935ce 100644 --- a/flashchips.h +++ b/flashchips.h @@ -838,6 +838,7 @@  #define ST_M50LPW116        0x30  #define ST_M29F002B        0x34    /* Same as M29F002BB */  #define ST_M29F002T        0xB0    /* Same as M29F002BT/M29F002NT/M29F002BNT */ +#define ST_M29F010B        0x20    /* Same as M29F010 */  #define ST_M29F040B        0xE2    /* Same as M29F040 */  #define ST_M29F080        0xF1  #define ST_M29F200BT        0xD3 diff --git a/flashrom.c b/flashrom.c index c89abad..267d0ef 100644 --- a/flashrom.c +++ b/flashrom.c @@ -108,6 +108,18 @@ const struct programmer_entry programmer_table[] = {      },  #endif +#if CONFIG_NICTULIP == 1 +    { +        .name            = "nictulip", +        .type            = PCI, +        .devs.dev        = nics_tulip, +        .init            = nictulip_init, +        .map_flash_region    = fallback_map, +        .unmap_flash_region    = fallback_unmap, +        .delay            = internal_delay, +    }, +#endif +  #if CONFIG_NICREALTEK == 1      {          /* This programmer works for Realtek RTL8139 and SMC 1211. */ diff --git a/programmer.h b/programmer.h index 29a100b..a9608e0 100644 --- a/programmer.h +++ b/programmer.h @@ -37,6 +37,9 @@ enum programmer {  #if CONFIG_NIC3COM == 1      PROGRAMMER_NIC3COM,  #endif +#if CONFIG_NICTULIP == 1 +    PROGRAMMER_NICTULIP, +#endif  #if CONFIG_NICREALTEK == 1      PROGRAMMER_NICREALTEK,  #endif @@ -410,6 +413,12 @@ int nic3com_init(void);  extern const struct dev_entry nics_3com[];  #endif +/* nictulip.c */ +#if CONFIG_NICTULIP == 1 +int nictulip_init(void); +extern const struct dev_entry nics_tulip[]; +#endif +  /* gfxnvidia.c */  #if CONFIG_GFXNVIDIA == 1  int gfxnvidia_init(void); diff --git a/nictulip.c b/nictulip.c new file mode 100644 index 0000000..bbea36a --- /dev/null +++ b/nictulip.c @@ -0,0 +1,118 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2021 Heiko Jehmlich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include "flash.h" +#include "programmer.h" +#include "hwaccess.h" + +#define CSR09        (io_base_addr + 0x48)    // Boot ROM, serial ROM, and MII management +#define CSR10        (io_base_addr + 0x50)    // Boot ROM programming address +#define CSR13        (io_base_addr + 0x68)    // SIA connectivity register + +static uint32_t io_base_addr = 0; +static uint16_t id; + +const struct dev_entry nics_tulip[] = { + +    {0x1011, 0x0014, OK, "DEC", "Digital Equipment Corporation DECchip 21041 [Tulip Pass 3]" }, +    {0x1011, 0x0009, OK, "DEC", "Digital Equipment Corporation DECchip 21140 [FasterNet]" }, +    {0x1011, 0x0019, OK, "DEC", "Digital Equipment Corporation DECchip 21143" }, + +    {0}, +}; + +static void nictulip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr) +{ +    uint32_t dword; + +    dword = 0; +    dword |= 1 << 13; // WRITE command +    dword |= 1 << 12; // select BOOT ROM +    dword |= val; // write data +    OUTL(dword, CSR09); + +    // no idea why we need to add 1 here +    dword = (addr & 0x3FFFF) + 1; +    OUTL(dword, CSR10); +} + +static uint8_t nictulip_readb(const struct flashctx *flash, const chipaddr addr) +{ +    uint32_t dword; + +    dword = 0; +    dword |= 1 << 14; // READ command +    dword |= 1 << 12; // select BOOT ROM +    OUTL(dword, CSR09); + +    // no idea why we need to add 1 here +    dword = (addr & 0x3FFFF) + 1; +    OUTL(dword, CSR10); + +    return (uint8_t) INL(CSR09) & 0xFF; +} + +static int nictulip_shutdown(void *data) +{ +    return 0; +} + +static const struct par_master par_master_nictulip = { +    .chip_readb        = nictulip_readb, +    .chip_readw        = fallback_chip_readw, +    .chip_readl        = fallback_chip_readl, +    .chip_readn        = fallback_chip_readn, +    .chip_writeb    = nictulip_writeb, +    .chip_writew    = fallback_chip_writew, +    .chip_writel    = fallback_chip_writel, +    .chip_writen    = fallback_chip_writen, +}; + +int nictulip_init(void) +{ +    struct pci_dev *dev = NULL; + +    if (rget_io_perms()) +        return 1; + +    dev = pcidev_init(nics_tulip, PCI_BASE_ADDRESS_0); +    if (!dev) +        return 1; + +    io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0); +    if (!io_base_addr) +        return 1; + +    id = dev->device_id; + +    if (register_shutdown(nictulip_shutdown, NULL)) +        return 1; + +    // CSR13 must be 0 before doing any boot ROM access. +    OUTL(0, CSR13); + +    register_par_master(&par_master_nictulip, BUS_PARALLEL);