diff options
Diffstat (limited to 'qemu/roms/u-boot/board/w7o')
-rw-r--r-- | qemu/roms/u-boot/board/w7o/Makefile | 13 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/cmd_vpd.c | 48 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/errors.h | 81 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/flash.c | 927 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/fpga.c | 371 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/fsboot.c | 74 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/init.S | 244 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/post1.S | 724 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/post2.c | 98 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/u-boot.lds.debug | 121 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/vpd.c | 412 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/vpd.h | 118 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/w7o.c | 257 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/w7o.h | 73 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/w7o/watchdog.c | 31 |
15 files changed, 3592 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/w7o/Makefile b/qemu/roms/u-boot/board/w7o/Makefile new file mode 100644 index 000000000..955de50e4 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2001 +# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = w7o.o flash.o fpga.o fsboot.o post2.o vpd.o cmd_vpd.o \ + watchdog.o +obj-y += init.o post1.o diff --git a/qemu/roms/u-boot/board/w7o/cmd_vpd.c b/qemu/roms/u-boot/board/w7o/cmd_vpd.c new file mode 100644 index 000000000..879cb6133 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/cmd_vpd.c @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> + +#if defined(CONFIG_CMD_BSP) + +#include "vpd.h" + +/* ====================================================================== + * Interpreter command to retrieve board specific Vital Product Data, "VPD" + * ====================================================================== + */ +int do_vpd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + VPD vpd; /* Board specific data struct */ + uchar dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR; + + /* Validate usage */ + if (argc > 2) + return cmd_usage(cmdtp); + + /* Passed in EEPROM address */ + if (argc == 2) + dev_addr = (uchar) simple_strtoul (argv[1], NULL, 16); + + /* Read VPD and output it */ + if (!vpd_get_data (dev_addr, &vpd)) { + vpd_print (&vpd); + return 0; + } + + return 1; +} + +U_BOOT_CMD( + vpd, 2, 1, do_vpd, + "Read Vital Product Data", + "[dev_addr]\n" + " - Read VPD Data from default address, or device address 'dev_addr'." +); + +#endif diff --git a/qemu/roms/u-boot/board/w7o/errors.h b/qemu/roms/u-boot/board/w7o/errors.h new file mode 100644 index 000000000..05540fb2d --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/errors.h @@ -0,0 +1,81 @@ +/* + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ERRORS_H_ +#define _ERRORS_H_ + +#define ERR_FF -1 /* led test value(2) */ +#define ERR_00 0x0000 /* led test value(2) */ +#define ERR_LED 0x01 /* led test failed (1)(3)(4) */ +#define ERR_RAMG 0x04 /* start SDRAM data bus test (2) */ +#define ERR_RAML 0x05 /* SDRAM data bus fault in LSW chip (5) */ +#define ERR_RAMH 0x06 /* SDRAM data bus fault in MSW chip (6) */ +#define ERR_RAMB 0x07 /* SDRAM data bus fault both chips (5)(6)(7) */ +#define ERR_ADDG 0x08 /* start Address ghosting test (13) */ +#define ERR_ADDF 0x09 /* fault during Address ghosting test (13) */ +#define ERR_POST1 0x0a /* post1 tests complete */ +#define ERR_TMP1 0x0b /* */ +#define ERR_R55G 0x0c /* start SDRAM fill 55 test (2) */ +#define ERR_R55L 0x0d /* SDRAM fill test 55 failed in LSW chip (8) */ +#define ERR_R55H 0x0e /* SDRAM fill test 55 failed in MSW chip (9) */ +#define ERR_R55B 0x0f /* SDRAM fill test 55 fail in both chips (10) */ +#define ERR_RAAG 0x10 /* start SDRAM fill aa test (2) */ +#define ERR_RAAL 0x11 /* SDRAM fill test aa failed in LSW chip (8) */ +#define ERR_RAAH 0x12 /* SDRAM fill test aa failed in MSW chip (9) */ +#define ERR_RAAB 0x13 /* SDRAM fill test aa fail in both chips (10) */ +#define ERR_R00G 0x14 /* start SDRAM fill 00 test (2) */ +#define ERR_R00L 0x15 /* SDRAM fill test 00 failed in LSW chip (8) */ +#define ERR_R00H 0x16 /* SDRAM fill test 00 failed in MSW chip (9) */ +#define ERR_R00B 0x17 /* SDRAM fill test 00 fail in both chips (10) */ +#define ERR_RTCG 0x18 /* start RTC test */ +#define ERR_RTCBAT 0x19 /* RTC battery failure */ +#define ERR_RTCTIM 0x1A /* RTC invalid time/date values */ +#define ERR_RTCVAL 0x1B /* RTC NVRAM not accessable */ +#define ERR_FPGAG 0x20 /* fault during FPGA programming */ +#define ERR_XRW1 0x21 /* Xilinx - can't read/write regs on FPGA 1 */ +#define ERR_XRW2 0x22 /* Xilinx - can't read/write regs on FPGA 2 */ +#define ERR_XRW3 0x23 /* Xilinx - can't read/write regs on FPGA 3 */ +#define ERR_XRW4 0x24 /* Xilinx - can't read/write regs on FPGA 4 */ +#define ERR_XRW5 0x25 /* Xilinx - can't read/write regs on FPGA 5 */ +#define ERR_XRW6 0x26 /* Xilinx - can't read/write regs on FPGA 6 */ +#define ERR_XINIT0 0x27 /* Xilinx - INIT line failed to go low */ +#define ERR_XINIT1 0x28 /* Xilinx - INIT line failed to go high */ +#define ERR_XDONE1 0x29 /* Xilinx - DONE line failed to go high */ +#define ERR_XIMAGE 0x2A /* Xilinx - Bad FPGA image in Flash */ +#define ERR_TempG 0x2b /* start temp sensor tests */ +#define ERR_Tinit0 0x2C /* temp sensor 0 failed to init */ +#define ERR_Tinit1 0x2D /* temp sensor 1 failed to init */ +#define ERR_Ttest0 0x2E /* temp sensor 0 failed test */ +#define ERR_Ttest1 0x2F /* temp sensor 1 failed test */ +#define ERR_lm75r 0x30 /* temp sensor read failure */ +#define ERR_lm75w 0x31 /* temp sensor write failure */ + + +#define ERR_POSTOK 0x55 /* PANIC: psych... OK */ + +#if !defined(__ASSEMBLY__) +extern void log_stat(int errcode); +extern void log_warn(int errcode); +extern void log_err(int errcode); +#endif + +/* +Debugging suggestions: +(1) periferal data bus shorted or crossed +(2) general processor halt, check reset, watch dog, power supply ripple, processor clock. +(3) check p_we, p_r/w, p_oe, p_rdy lines. +(4) check LED buffers +(5) check SDRAM data bus bits 16-31, check LSW SDRAM chip. +(6) check SDRAM data bus bits 0-15, check MSW SDRAM chip. +(7) check SDRAM control lines and clocks +(8) check decoupling caps, replace LSW SDRAM +(9) check decoupling caps, replace MSW SDRAM +(10) +(11) +(12) +(13) SDRAM address shorted or unconnected, check sdram caps +*/ +#endif /* _ERRORS_H_ */ diff --git a/qemu/roms/u-boot/board/w7o/flash.c b/qemu/roms/u-boot/board/w7o/flash.c new file mode 100644 index 000000000..26bddc423 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/flash.c @@ -0,0 +1,927 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * Based on code by: + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/processor.h> + +#include <watchdog.h> + +/* info for FLASH chips */ +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +/* + * Functions + */ +static ulong flash_get_size(vu_long *addr, flash_info_t *info); +static int write_word8(flash_info_t *info, ulong dest, ulong data); +static int write_word32(flash_info_t *info, ulong dest, ulong data); +static void flash_get_offsets(ulong base, flash_info_t *info); + +unsigned long flash_init(void) +{ + int i; + unsigned long size_b0, base_b0; + unsigned long size_b1; + + /* Init: no FLASHes known */ + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) + flash_info[i].flash_id = FLASH_UNKNOWN; + + /* Get Size of Boot and Main Flashes */ + size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM, + &flash_info[0]); + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0 << 20); + return 0; + } + size_b1 = + flash_get_size((vu_long *) FLASH_BASE1_PRELIM, + &flash_info[1]); + if (flash_info[1].flash_id == FLASH_UNKNOWN) { + printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n", + size_b1, size_b1 << 20); + return 0; + } + + /* Calculate base addresses */ + base_b0 = -size_b0; + + /* Setup offsets for Boot Flash */ + flash_get_offsets(base_b0, &flash_info[0]); + + /* Protect board level data */ + (void) flash_protect(FLAG_PROTECT_SET, + base_b0, + flash_info[0].start[1] - 1, &flash_info[0]); + + /* Monitor protection ON by default */ + (void) flash_protect(FLAG_PROTECT_SET, + base_b0 + size_b0 - monitor_flash_len, + base_b0 + size_b0 - 1, &flash_info[0]); + + /* Protect the FPGA image */ + (void) flash_protect(FLAG_PROTECT_SET, + FLASH_BASE1_PRELIM, + FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN - + 1, &flash_info[1]); + + /* Protect the default boot image */ + (void) flash_protect(FLAG_PROTECT_SET, + FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN, + FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN + + 0x600000 - 1, &flash_info[1]); + + /* Setup offsets for Main Flash */ + flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]); + + return size_b0 + size_b1; +} + +static void flash_get_offsets(ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start address table - FOR BOOT ROM ONLY!!! */ + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) { + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + } +} /* end flash_get_offsets() */ + +void flash_print_info(flash_info_t *info) +{ + int i; + int k; + int size; + int erased; + volatile unsigned long *flash; + + if (info->flash_id == FLASH_UNKNOWN) { + printf("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: + printf("1 x AMD "); + break; + case FLASH_MAN_STM: + printf("1 x STM "); + break; + case FLASH_MAN_INTEL: + printf("2 x Intel "); + break; + default: + printf("Unknown Vendor "); + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM040: + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) + printf("AM29LV040 (4096 Kbit, uniform sector size)\n"); + else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) + printf("M29W040B (4096 Kbit, uniform block size)\n"); + else + printf("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n"); + break; + case FLASH_28F320J3A: + printf("28F320J3A (32 Mbit = 128K x 32)\n"); + break; + case FLASH_28F640J3A: + printf("28F640J3A (64 Mbit = 128K x 64)\n"); + break; + case FLASH_28F128J3A: + printf("28F128J3A (128 Mbit = 128K x 128)\n"); + break; + default: + printf("Unknown Chip Type\n"); + } + + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) { + printf(" Size: %ld KB in %d Blocks\n", + info->size >> 10, info->sector_count); + } else { + printf(" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + } + + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + /* + * Check if whole sector is erased + */ + if (i != (info->sector_count - 1)) + size = info->start[i + 1] - info->start[i]; + else + size = info->start[0] + info->size - info->start[i]; + erased = 1; + flash = (volatile unsigned long *) info->start[i]; + size = size >> 2; /* divide by 4 for longword access */ + for (k = 0; k < size; k++) { + if (*flash++ != 0xffffffff) { + erased = 0; + break; + } + } + + if ((i % 5) == 0) + printf("\n "); + printf(" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " "); + } + printf("\n"); +} /* end flash_print_info() */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size(vu_long *addr, flash_info_t *info) +{ + short i; + ulong base = (ulong) addr; + + /* Setup default type */ + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + + /* Test for Boot Flash */ + if (base == FLASH_BASE0_PRELIM) { + unsigned char value; + volatile unsigned char *addr2 = (unsigned char *) addr; + + /* Write auto select command: read Manufacturer ID */ + *(addr2 + 0x555) = 0xaa; + *(addr2 + 0x2aa) = 0x55; + *(addr2 + 0x555) = 0x90; + + /* Manufacture ID */ + value = *addr2; + switch (value) { + case (unsigned char) AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (unsigned char) STM_MANUFACT: + info->flash_id = FLASH_MAN_STM; + break; + default: + *addr2 = 0xf0; /* no or unknown flash */ + return 0; + } + + /* Device ID */ + value = *(addr2 + 1); + switch (value) { + case (unsigned char) AMD_ID_LV040B: + case (unsigned char) STM_ID_29W040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x00080000; + break; /* => 512Kb */ + default: + *addr2 = 0xf0; /* => no or unknown flash */ + return 0; + } + } else { /* MAIN Flash */ + unsigned long value; + volatile unsigned long *addr2 = (unsigned long *) addr; + + /* Write auto select command: read Manufacturer ID */ + *addr2 = 0x90909090; + + /* Manufacture ID */ + value = *addr2; + switch (value) { + case (unsigned long) INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + default: + *addr2 = 0xff; /* no or unknown flash */ + return 0; + } + + /* Device ID - This shit is interleaved... */ + value = *(addr2 + 1); + switch (value) { + case (unsigned long) INTEL_ID_28F320J3A: + info->flash_id += FLASH_28F320J3A; + info->sector_count = 32; + info->size = 0x00400000 * 2; + break; /* => 2 X 4 MB */ + case (unsigned long) INTEL_ID_28F640J3A: + info->flash_id += FLASH_28F640J3A; + info->sector_count = 64; + info->size = 0x00800000 * 2; + break; /* => 2 X 8 MB */ + case (unsigned long) INTEL_ID_28F128J3A: + info->flash_id += FLASH_28F128J3A; + info->sector_count = 128; + info->size = 0x01000000 * 2; + break; /* => 2 X 16 MB */ + default: + *addr2 = 0xff; /* => no or unknown flash */ + } + } + + /* Make sure we don't exceed CONFIG_SYS_MAX_FLASH_SECT */ + if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) { + printf("** ERROR: sector count %d > max (%d) **\n", + info->sector_count, CONFIG_SYS_MAX_FLASH_SECT); + info->sector_count = CONFIG_SYS_MAX_FLASH_SECT; + } + + /* set up sector start address table */ + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM040: + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + break; + case FLASH_28F320J3A: + case FLASH_28F640J3A: + case FLASH_28F128J3A: + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + + (i * 0x00020000 * 2); /* 2 Banks */ + break; + } + + /* Test for Boot Flash */ + if (base == FLASH_BASE0_PRELIM) { + volatile unsigned char *addr2; + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* + * read sector protection at sector address, + * (AX .. A0) = 0x02 + * D0 = 1 if protected + */ + addr2 = (volatile unsigned char *) (info->start[i]); + info->protect[i] = *(addr2 + 2) & 1; + } + + /* Restore read mode */ + *(unsigned char *) base = 0xF0; /* Reset NORMAL Flash */ + } else { /* Main Flash */ + volatile unsigned long *addr2; + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* + * read sector protection at sector address, + * (AX .. A0) = 0x02 + * D0 = 1 if protected + */ + addr2 = (volatile unsigned long *) (info->start[i]); + info->protect[i] = *(addr2 + 2) & 0x1; + } + + /* Restore read mode */ + *(unsigned long *) base = 0xFFFFFFFF; /* Reset Flash */ + } + + return info->size; +} /* end flash_get_size() */ + +static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout) +{ + int i; + + volatile uchar *vaddr = (uchar *) addr; + + /* Loop X times */ + for (i = 1; i <= (100 * tout); i++) { /* Wait up to tout ms */ + udelay(10); + /* Pause 10 us */ + + /* Check for completion */ + if ((vaddr[0] & 0x80) == (cmp_val & 0x80)) + return 0; + + /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */ + if (!(i % 110000)) + putc('.'); + + /* Kick the dog if needed */ + WATCHDOG_RESET(); + } + + return 1; +} /* wait_for_DQ7() */ + +static int flash_erase8(flash_info_t *info, int s_first, int s_last) +{ + int tcode, rcode = 0; + volatile uchar *addr = (uchar *) (info->start[0]); + volatile uchar *sector_addr; + int flag, prot, sect; + + /* Validate arguments */ + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) + printf("- missing\n"); + else + printf("- no sectors to erase\n"); + return 1; + } + + /* Check for KNOWN flash type */ + if (info->flash_id == FLASH_UNKNOWN) { + printf("Can't erase unknown flash type - aborted\n"); + return 1; + } + + /* Check for protected sectors */ + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) + prot++; + } + if (prot) { + printf("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf("\n"); + } + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + sector_addr = (uchar *) (info->start[sect]); + + if ((info->flash_id & FLASH_VENDMASK) == + FLASH_MAN_STM) + printf("Erasing block %p\n", sector_addr); + else + printf("Erasing sector %p\n", sector_addr); + + /* Disable interrupts which might cause timeout */ + flag = disable_interrupts(); + + *(addr + 0x555) = (uchar) 0xAA; + *(addr + 0x2aa) = (uchar) 0x55; + *(addr + 0x555) = (uchar) 0x80; + *(addr + 0x555) = (uchar) 0xAA; + *(addr + 0x2aa) = (uchar) 0x55; + *sector_addr = (uchar) 0x30; /* sector erase */ + + /* + * Wait for each sector to complete, it's more + * reliable. According to AMD Spec, you must + * issue all erase commands within a specified + * timeout. This has been seen to fail, especially + * if printf()s are included (for debug)!! + * Takes up to 6 seconds. + */ + tcode = wait_for_DQ7((ulong) sector_addr, 0x80, 6000); + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* Make sure we didn't timeout */ + if (tcode) { + printf("Timeout\n"); + rcode = 1; + } + } + } + + /* wait at least 80us - let's wait 1 ms */ + udelay(1000); + + /* reset to read mode */ + addr = (uchar *) info->start[0]; + *addr = (uchar) 0xF0; /* reset bank */ + + printf(" done\n"); + return rcode; +} /* end flash_erase8() */ + +static int flash_erase32(flash_info_t *info, int s_first, int s_last) +{ + int flag, sect; + ulong start, now, last; + int prot = 0; + + /* Validate arguments */ + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) + printf("- missing\n"); + else + printf("- no sectors to erase\n"); + return 1; + } + + /* Check for KNOWN flash type */ + if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { + printf("Can erase only Intel flash types - aborted\n"); + return 1; + } + + /* Check for protected sectors */ + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) + prot++; + } + if (prot) { + printf("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf("\n"); + } + + start = get_timer(0); + last = start; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + WATCHDOG_RESET(); + if (info->protect[sect] == 0) { /* not protected */ + vu_long *addr = (vu_long *) (info->start[sect]); + unsigned long status; + + /* Disable interrupts which might cause a timeout */ + flag = disable_interrupts(); + + *addr = 0x00500050; /* clear status register */ + *addr = 0x00200020; /* erase setup */ + *addr = 0x00D000D0; /* erase confirm */ + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* Wait at least 80us - let's wait 1 ms */ + udelay(1000); + + while (((status = *addr) & 0x00800080) != 0x00800080) { + now = get_timer(start); + if (now > CONFIG_SYS_FLASH_ERASE_TOUT) { + printf("Timeout\n"); + /* suspend erase */ + *addr = 0x00B000B0; + /* reset to read mode */ + *addr = 0x00FF00FF; + return 1; + } + + /* + * show that we're waiting + * every second (?) + */ + if ((now - last) > 990) { + putc('.'); + last = now; + } + } + *addr = 0x00FF00FF; /* reset to read mode */ + } + } + printf(" done\n"); + return 0; +} + +int flash_erase(flash_info_t *info, int s_first, int s_last) +{ + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) + return flash_erase8(info, s_first, s_last); + else + return flash_erase32(info, s_first, s_last); +} + +/* + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_buff8(flash_info_t *info, uchar *src, ulong addr, + ulong cnt) +{ + ulong cp, wp, data; + ulong start; + int i, l, rc; + + start = get_timer(0); + + wp = (addr & ~3); /* get lower word + aligned address */ + + /* + * handle unaligned start bytes + */ + l = addr - wp; + if (l != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + for (; i < 4 && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + + for (; cnt == 0 && i < 4; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + rc = write_word8(info, wp, data); + if (rc != 0) + return rc; + + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i = 0; i < 4; ++i) + data = (data << 8) | *src++; + + rc = write_word8(info, wp, data); + if (rc != 0) + return rc; + + wp += 4; + cnt -= 4; + if (get_timer(start) > 1000) { /* every second */ + WATCHDOG_RESET(); + putc('.'); + start = get_timer(0); + } + } + + if (cnt == 0) + return 0; + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + + for (; i < 4; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + return write_word8(info, wp, data); +} + +#define FLASH_WIDTH 4 /* flash bus width in bytes */ +static int write_buff32(flash_info_t *info, uchar *src, ulong addr, + ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + ulong start; + + start = get_timer(0); + + if (info->flash_id == FLASH_UNKNOWN) + return 4; + + /* get lower FLASH_WIDTH aligned address */ + wp = (addr & ~(FLASH_WIDTH - 1)); + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i = 0, cp = wp; i < l; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + for (; i < FLASH_WIDTH && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + + for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + rc = write_word32(info, wp, data); + if (rc != 0) + return rc; + + wp += FLASH_WIDTH; + } + + /* + * handle FLASH_WIDTH aligned part + */ + while (cnt >= FLASH_WIDTH) { + data = 0; + for (i = 0; i < FLASH_WIDTH; ++i) + data = (data << 8) | *src++; + + rc = write_word32(info, wp, data); + if (rc != 0) + return rc; + + wp += FLASH_WIDTH; + cnt -= FLASH_WIDTH; + if (get_timer(start) > 990) { /* every second */ + putc('.'); + start = get_timer(0); + } + } + + if (cnt == 0) + return 0; + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + + for (; i < FLASH_WIDTH; ++i, ++cp) + data = (data << 8) | (*(uchar *) cp); + + return write_word32(info, wp, data); +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + int retval; + + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) + retval = write_buff8(info, src, addr, cnt); + else + retval = write_buff32(info, src, addr, cnt); + + return retval; +} + +/* + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +static int write_word8(flash_info_t *info, ulong dest, ulong data) +{ + volatile uchar *addr2 = (uchar *) (info->start[0]); + volatile uchar *dest2 = (uchar *) dest; + volatile uchar *data2 = (uchar *) &data; + int flag; + int i, tcode, rcode = 0; + + /* Check if Flash is (sufficently) erased */ + if ((*((volatile uchar *)dest) & (uchar)data) != (uchar)data) + return 2; + + for (i = 0; i < (4 / sizeof(uchar)); i++) { + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + *(addr2 + 0x555) = (uchar) 0xAA; + *(addr2 + 0x2aa) = (uchar) 0x55; + *(addr2 + 0x555) = (uchar) 0xA0; + + dest2[i] = data2[i]; + + /* Wait for write to complete, up to 1ms */ + tcode = wait_for_DQ7((ulong) &dest2[i], data2[i], 1); + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* Make sure we didn't timeout */ + if (tcode) + rcode = 1; + } + + return rcode; +} + +static int write_word32(flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long *) dest; + ulong status; + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & data) != data) + return 2; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + *addr = 0x00400040; /* write setup */ + *addr = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + start = get_timer(0); + + while (((status = *addr) & 0x00800080) != 0x00800080) { + WATCHDOG_RESET(); + if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + *addr = 0x00FF00FF; /* restore read mode */ + return 1; + } + } + + *addr = 0x00FF00FF; /* restore read mode */ + + return 0; +} + +static int _flash_protect(flash_info_t *info, long sector) +{ + int i; + int flag; + ulong status; + int rcode = 0; + volatile long *addr = (long *)sector; + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F320J3A: + case FLASH_28F640J3A: + case FLASH_28F128J3A: + /* Disable interrupts which might cause Flash to timeout */ + flag = disable_interrupts(); + + /* Issue command */ + *addr = 0x00500050L; /* Clear the status register */ + *addr = 0x00600060L; /* Set lock bit setup */ + *addr = 0x00010001L; /* Set lock bit confirm */ + + /* Wait for command completion */ + for (i = 0; i < 10; i++) { /* 75us timeout, wait 100us */ + udelay(10); + if ((*addr & 0x00800080L) == 0x00800080L) + break; + } + + /* Not successful? */ + status = *addr; + if (status != 0x00800080L) { + printf("Protect %x sector failed: %x\n", + (uint) sector, (uint) status); + rcode = 1; + } + + /* Restore read mode */ + *addr = 0x00ff00ffL; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + break; + case FLASH_AM040: /* No soft sector protection */ + break; + } + + /* Turn protection on for this sector */ + for (i = 0; i < info->sector_count; i++) { + if (info->start[i] == sector) { + info->protect[i] = 1; + break; + } + } + + return rcode; +} + +static int _flash_unprotect(flash_info_t *info, long sector) +{ + int i; + int flag; + ulong status; + int rcode = 0; + volatile long *addr = (long *) sector; + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F320J3A: + case FLASH_28F640J3A: + case FLASH_28F128J3A: + /* Disable interrupts which might cause Flash to timeout */ + flag = disable_interrupts(); + + *addr = 0x00500050L; /* Clear the status register */ + *addr = 0x00600060L; /* Clear lock bit setup */ + *addr = 0x00D000D0L; /* Clear lock bit confirm */ + + /* Wait for command completion */ + for (i = 0; i < 80; i++) { /* 700ms timeout, wait 800 */ + udelay(10000); /* Delay 10ms */ + if ((*addr & 0x00800080L) == 0x00800080L) + break; + } + + /* Not successful? */ + status = *addr; + if (status != 0x00800080L) { + printf("Un-protect %x sector failed: %x\n", + (uint) sector, (uint) status); + *addr = 0x00ff00ffL; + rcode = 1; + } + + /* restore read mode */ + *addr = 0x00ff00ffL; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + break; + case FLASH_AM040: /* No soft sector protection */ + break; + } + + /* + * Fix Intel's little red wagon. Reprotect + * sectors that were protected before we undid + * protection on a specific sector. + */ + for (i = 0; i < info->sector_count; i++) { + if (info->start[i] != sector) { + if (info->protect[i]) { + if (_flash_protect(info, info->start[i])) + rcode = 1; + } + } else /* Turn protection off for this sector */ + info->protect[i] = 0; + } + + return rcode; +} + +int flash_real_protect(flash_info_t *info, long sector, int prot) +{ + int rcode; + + if (prot) + rcode = _flash_protect(info, info->start[sector]); + else + rcode = _flash_unprotect(info, info->start[sector]); + + return rcode; +} diff --git a/qemu/roms/u-boot/board/w7o/fpga.c b/qemu/roms/u-boot/board/w7o/fpga.c new file mode 100644 index 000000000..a27e8ab88 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/fpga.c @@ -0,0 +1,371 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com + * and + * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <config.h> +#include <common.h> +#include "w7o.h" +#include <asm/processor.h> +#include <linux/compiler.h> +#include "errors.h" + +static void +fpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr) +{ + unsigned long i; + volatile unsigned long val; + volatile unsigned short *dest = daddr; /* volatile-bypass optimizer */ + + for (i = 0; i < len; i++, src++) { + val = *src; + *dest = (unsigned short) ((val & 0xff000000L) >> 16); + *dest = (unsigned short) ((val & 0x00ff0000L) >> 8); + *dest = (unsigned short) (val & 0x0000ff00L); + *dest = (unsigned short) ((val & 0x000000ffL) << 8); + } + + /* Terminate programming with 4 C clocks */ + dest = daddr; + val = *(unsigned short *) dest; + val = *(unsigned short *) dest; + val = *(unsigned short *) dest; + val = *(unsigned short *) dest; + +} + + +int +fpgaDownload(unsigned char *saddr, unsigned long size, unsigned short *daddr) +{ + int i; /* index, intr disable flag */ + int start; /* timer */ + unsigned long greg, grego; /* GPIO & output register */ + unsigned long length; /* image size in words */ + unsigned long *source; /* image source addr */ + unsigned short *dest; /* destination FPGA addr */ + volatile unsigned short *ndest; /* temp dest FPGA addr */ + unsigned long cnfg = GPIO_XCV_CNFG; /* FPGA CNFG */ + unsigned long eirq = GPIO_XCV_IRQ; + int retval = -1; /* Function return value */ + __maybe_unused volatile unsigned short val; /* temp val */ + + /* Setup some basic values */ + length = (size / 4) + 1; /* size in words, rounding UP + is OK */ + source = (unsigned long *) saddr; + dest = (unsigned short *) daddr; + + /* Get DCR output register */ + grego = in32(PPC405GP_GPIO0_OR); + + /* Reset FPGA */ + grego &= ~GPIO_XCV_PROG; /* PROG line low */ + out32(PPC405GP_GPIO0_OR, grego); + + /* Setup timeout timer */ + start = get_timer(0); + + /* Wait for FPGA init line to go low */ + while (in32(PPC405GP_GPIO0_IR) & GPIO_XCV_INIT) { + /* Check for timeout - 100us max, so use 3ms */ + if (get_timer(start) > 3) { + printf(" failed to start init.\n"); + log_warn(ERR_XINIT0); /* Don't halt */ + + /* Reset line stays low */ + goto done; /* I like gotos... */ + } + } + + /* Unreset FPGA */ + grego |= GPIO_XCV_PROG; /* PROG line high */ + out32(PPC405GP_GPIO0_OR, grego); + + /* Wait for FPGA end of init period = init line go hi */ + while (!(in32(PPC405GP_GPIO0_IR) & GPIO_XCV_INIT)) { + + /* Check for timeout */ + if (get_timer(start) > 3) { + printf(" failed to exit init.\n"); + log_warn(ERR_XINIT1); + + /* Reset FPGA */ + grego &= ~GPIO_XCV_PROG; /* PROG line low */ + out32(PPC405GP_GPIO0_OR, grego); + + goto done; + } + } + + /* Now program FPGA ... */ + ndest = dest; + for (i = 0; i < CONFIG_NUM_FPGAS; i++) { + /* Toggle IRQ/GPIO */ + greg = mfdcr(CPC0_CR0); /* get chip ctrl register */ + greg |= eirq; /* toggle irq/gpio */ + mtdcr(CPC0_CR0, greg); /* ... just do it */ + + /* turn on open drain for CNFG */ + greg = in32(PPC405GP_GPIO0_ODR); /* get open drain register */ + greg |= cnfg; /* CNFG open drain */ + out32(PPC405GP_GPIO0_ODR, greg); /* .. just do it */ + + /* Turn output enable on for CNFG */ + greg = in32(PPC405GP_GPIO0_TCR); /* get tristate register */ + greg |= cnfg; /* CNFG tristate inactive */ + out32(PPC405GP_GPIO0_TCR, greg); /* ... just do it */ + + /* Setup FPGA for programming */ + grego &= ~cnfg; /* CONFIG line low */ + out32(PPC405GP_GPIO0_OR, grego); + + /* + * Program the FPGA + */ + printf("\n destination: 0x%lx ", (unsigned long) ndest); + + fpga_img_write(source, length, (unsigned short *) ndest); + + /* Done programming */ + grego |= cnfg; /* CONFIG line high */ + out32(PPC405GP_GPIO0_OR, grego); + + /* Turn output enable OFF for CNFG */ + greg = in32(PPC405GP_GPIO0_TCR); /* get tristate register */ + greg &= ~cnfg; /* CNFG tristate inactive */ + out32(PPC405GP_GPIO0_TCR, greg); /* ... just do it */ + + /* Toggle IRQ/GPIO */ + greg = mfdcr(CPC0_CR0); /* get chip ctrl register */ + greg &= ~eirq; /* toggle irq/gpio */ + mtdcr(CPC0_CR0, greg); /* ... just do it */ + + /* XXX - Next FPGA addr */ + ndest = (unsigned short *) ((char *) ndest + 0x00100000L); + cnfg >>= 1; /* XXX - Next */ + eirq >>= 1; + } + + /* Terminate programming with 4 C clocks */ + ndest = dest; + for (i = 0; i < CONFIG_NUM_FPGAS; i++) { + val = *ndest; + val = *ndest; + val = *ndest; + val = *ndest; + ndest = (unsigned short *) ((char *) ndest + 0x00100000L); + } + + /* Setup timer */ + start = get_timer(0); + + /* Wait for FPGA end of programming period = Test DONE low */ + while (!(in32(PPC405GP_GPIO0_IR) & GPIO_XCV_DONE)) { + + /* Check for timeout */ + if (get_timer(start) > 3) { + printf(" done failed to come high.\n"); + log_warn(ERR_XDONE1); + + /* Reset FPGA */ + grego &= ~GPIO_XCV_PROG; /* PROG line low */ + out32(PPC405GP_GPIO0_OR, grego); + + goto done; + } + } + + printf("\n FPGA load succeeded\n"); + retval = 0; /* Program OK */ + +done: + return retval; +} + +/* FPGA image is stored in flash */ +extern flash_info_t flash_info[]; + +int init_fpga(void) +{ + unsigned int i, j, ptr; /* General purpose */ + unsigned char bufchar; /* General purpose character */ + unsigned char *buf; /* Start of image pointer */ + unsigned long len; /* Length of image */ + unsigned char *fn_buf; /* Start of filename string */ + unsigned int fn_len; /* Length of filename string */ + unsigned char *xcv_buf; /* Pointer to start of image */ + unsigned long xcv_len; /* Length of image */ + unsigned long crc; /* 30bit crc in image */ + unsigned long calc_crc; /* Calc'd 30bit crc */ + int retval = -1; + + /* Tell the world what we are doing */ + printf("FPGA: "); + + /* + * Get address of first sector where the FPGA + * image is stored. + */ + buf = (unsigned char *) flash_info[1].start[0]; + + /* + * Get the stored image's CRC & length. + */ + crc = *(unsigned long *) (buf + 4); /* CRC is first long word */ + len = *(unsigned long *) (buf + 8); /* Image len is next long */ + + /* Pedantic */ + if ((len < 0x133A4) || (len > 0x80000)) + goto bad_image; + + /* + * Get the file name pointer and length. + * filename length is next short + */ + fn_len = (*(unsigned short *) (buf + 12) & 0xff); + fn_buf = buf + 14; + + /* + * Get the FPGA image pointer and length length. + */ + xcv_buf = fn_buf + fn_len; /* pointer to fpga image */ + xcv_len = len - 14 - fn_len; /* fpga image length */ + + /* Check for uninitialized FLASH */ + if ((strncmp((char *) buf, "w7o", 3) != 0) || (len > 0x0007ffffL) + || (len == 0)) + goto bad_image; + + /* + * Calculate and Check the image's CRC. + */ + calc_crc = crc32(0, xcv_buf, xcv_len); + if (crc != calc_crc) { + printf("\nfailed - bad CRC\n"); + goto done; + } + + /* Output the file name */ + printf("file name : "); + for (i = 0; i < fn_len; i++) { + bufchar = fn_buf[+i]; + if (bufchar < ' ' || bufchar > '~') + bufchar = '.'; + putc(bufchar); + } + + /* + * find rest of display data + */ + ptr = 15; /* Offset to ncd filename + length in fpga image */ + j = xcv_buf[ptr]; /* Get len of ncd filename */ + if (j > 32) + goto bad_image; + ptr = ptr + j + 3; /* skip ncd filename string + + 3 bytes more bytes */ + + /* + * output target device string + */ + j = xcv_buf[ptr++] - 1; /* len of targ str less term */ + if (j > 32) + goto bad_image; + printf("\n target : "); + for (i = 0; i < j; i++) { + bufchar = (xcv_buf[ptr++]); + if (bufchar < ' ' || bufchar > '~') + bufchar = '.'; + putc(bufchar); + } + + /* + * output compilation date string and time string + */ + ptr += 3; /* skip 2 bytes */ + printf("\n synth time : "); + j = (xcv_buf[ptr++] - 1); /* len of date str less term */ + if (j > 32) + goto bad_image; + for (i = 0; i < j; i++) { + bufchar = (xcv_buf[ptr++]); + if (bufchar < ' ' || bufchar > '~') + bufchar = '.'; + putc(bufchar); + } + + ptr += 3; /* Skip 2 bytes */ + printf(" - "); + j = (xcv_buf[ptr++] - 1); /* slen = targ dev str len */ + if (j > 32) + goto bad_image; + for (i = 0; i < j; i++) { + bufchar = (xcv_buf[ptr++]); + if (bufchar < ' ' || bufchar > '~') + bufchar = '.'; + putc(bufchar); + } + + /* + * output crc and length strings + */ + printf("\n len & crc : 0x%lx 0x%lx", len, crc); + + /* + * Program the FPGA. + */ + retval = fpgaDownload((unsigned char *) xcv_buf, xcv_len, + (unsigned short *) 0xfd000000L); + return retval; + +bad_image: + printf("\n BAD FPGA image format @ %lx\n", + flash_info[1].start[0]); + log_warn(ERR_XIMAGE); +done: + return retval; +} + +void test_fpga(unsigned short *daddr) +{ + int i; + volatile unsigned short *ndest = daddr; + + for (i = 0; i < CONFIG_NUM_FPGAS; i++) { +#if defined(CONFIG_W7OLMG) + ndest[0x7e] = 0x55aa; + if (ndest[0x7e] != 0x55aa) + log_warn(ERR_XRW1 + i); + ndest[0x7e] = 0xaa55; + if (ndest[0x7e] != 0xaa55) + log_warn(ERR_XRW1 + i); + ndest[0x7e] = 0xc318; + if (ndest[0x7e] != 0xc318) + log_warn(ERR_XRW1 + i); + +#elif defined(CONFIG_W7OLMC) + ndest[0x800] = 0x55aa; + ndest[0x801] = 0xaa55; + ndest[0x802] = 0xc318; + ndest[0x4800] = 0x55aa; + ndest[0x4801] = 0xaa55; + ndest[0x4802] = 0xc318; + if ((ndest[0x800] != 0x55aa) || + (ndest[0x801] != 0xaa55) || (ndest[0x802] != 0xc318)) + log_warn(ERR_XRW1 + (2 * i)); /* Auto gen error code */ + if ((ndest[0x4800] != 0x55aa) || + (ndest[0x4801] != 0xaa55) || (ndest[0x4802] != 0xc318)) + log_warn(ERR_XRW2 + (2 * i)); /* Auto gen error code */ + +#else +#error "Unknown W7O board configuration" +#endif + } + + printf(" FPGA ready\n"); + return; +} diff --git a/qemu/roms/u-boot/board/w7o/fsboot.c b/qemu/roms/u-boot/board/w7o/fsboot.c new file mode 100644 index 000000000..25fbb55c8 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/fsboot.c @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2001 + * Wave 7 Optics, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <command.h> + +/* + * FIXME: Add code to test image and it's header. + */ +extern int valid_elf_image (unsigned long addr); + +static int +image_check(ulong addr) +{ + return valid_elf_image(addr); +} + +void +init_fsboot(void) +{ + char *envp; + ulong loadaddr; + ulong testaddr; + ulong alt_loadaddr; + char buf[9]; + + /* + * Get test image address + */ + if ((envp = getenv("testaddr")) != NULL) + testaddr = simple_strtoul(envp, NULL, 16); + else + testaddr = -1; + + /* + * Are we going to test boot and image? + */ + if ((testaddr != -1) && image_check(testaddr)) { + + /* Set alt_loadaddr */ + alt_loadaddr = testaddr; + sprintf(buf, "%lX", alt_loadaddr); + setenv("alt_loadaddr", buf); + + /* Clear test_addr */ + setenv("testaddr", NULL); + + /* + * Save current environment with alt_loadaddr, + * and cleared testaddr. + */ + saveenv(); + + /* + * Setup temporary loadaddr to alt_loadaddr + * XXX - DO NOT SAVE ENVIRONMENT! + */ + loadaddr = alt_loadaddr; + sprintf(buf, "%lX", loadaddr); + setenv("loadaddr", buf); + + } else { /* Normal boot */ + setenv("alt_loadaddr", NULL); /* Clear alt_loadaddr */ + setenv("testaddr", NULL); /* Clear testaddr */ + saveenv(); + } + + return; +} diff --git a/qemu/roms/u-boot/board/w7o/init.S b/qemu/roms/u-boot/board/w7o/init.S new file mode 100644 index 000000000..dfde14995 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/init.S @@ -0,0 +1,244 @@ +/* + * SPDX-License-Identifier: GPL-2.0 IBM-pibs + */ +#include <config.h> +#include <asm/ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +/****************************************************************************** + * Function: ext_bus_cntlr_init + * + * Description: Configures EBC Controller and a few basic chip selects. + * + * CS0 is setup to get the Boot Flash out of the addresss range + * so that we may setup a stack. CS7 is setup so that we can + * access and reset the hardware watchdog. + * + * IMPORTANT: For pass1 this code must run from + * cache since you can not reliably change a peripheral banks + * timing register (pbxap) while running code from that bank. + * For ex., since we are running from ROM on bank 0, we can NOT + * execute the code that modifies bank 0 timings from ROM, so + * we run it from cache. + * + * Notes: Does NOT use the stack. + *****************************************************************************/ + .section ".text" + .align 2 + .globl ext_bus_cntlr_init + .type ext_bus_cntlr_init, @function +ext_bus_cntlr_init: + mflr r0 + /******************************************************************** + * Prefetch entire ext_bus_cntrl_init function into the icache. + * This is necessary because we are going to change the same CS we + * are executing from. Otherwise a CPU lockup may occur. + *******************************************************************/ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + + /* Calculate number of cache lines for this function */ + addi r4, 0, (((.Lfe0 - ..getAddr) / CONFIG_SYS_CACHELINE_SIZE) + 2) + mtctr r4 +..ebcloop: + icbt r0, r3 /* prefetch cache line for addr in r3*/ + addi r3, r3, CONFIG_SYS_CACHELINE_SIZE /* move to next cache line */ + bdnz ..ebcloop /* continue for $CTR cache lines */ + + /******************************************************************** + * Delay to ensure all accesses to ROM are complete before changing + * bank 0 timings. 200usec should be enough. + * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles. + *******************************************************************/ + addis r3, 0, 0x0 + ori r3, r3, 0xA000 /* wait 200us from reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /******************************************************************** + * Setup External Bus Controller (EBC). + *******************************************************************/ + addi r3, 0, EBC0_CFG + mtdcr EBC0_CFGADDR, r3 + addis r4, 0, 0xb040 /* Device base timeout = 1024 cycles */ + ori r4, r4, 0x0 /* Drive CS with external master */ + mtdcr EBC0_CFGDATA, r4 + + /******************************************************************** + * Change PCIINT signal to PerWE + *******************************************************************/ + mfdcr r4, CPC0_CR1 + ori r4, r4, 0x4000 + mtdcr CPC0_CR1, r4 + + /******************************************************************** + * Memory Bank 0 (Flash Bank 0) initialization + *******************************************************************/ + addi r3, 0, PB1AP + mtdcr EBC0_CFGADDR, r3 + addis r4, 0, CONFIG_SYS_W7O_EBC_PB0AP@h + ori r4, r4, CONFIG_SYS_W7O_EBC_PB0AP@l + mtdcr EBC0_CFGDATA, r4 + + addi r3, 0, PB0CR + mtdcr EBC0_CFGADDR, r3 + addis r4, 0, CONFIG_SYS_W7O_EBC_PB0CR@h + ori r4, r4, CONFIG_SYS_W7O_EBC_PB0CR@l + mtdcr EBC0_CFGDATA, r4 + + /******************************************************************** + * Memory Bank 7 LEDs - NEEDED BECAUSE OF HW WATCHDOG AND LEDs. + *******************************************************************/ + addi r3, 0, PB7AP + mtdcr EBC0_CFGADDR, r3 + addis r4, 0, CONFIG_SYS_W7O_EBC_PB7AP@h + ori r4, r4, CONFIG_SYS_W7O_EBC_PB7AP@l + mtdcr EBC0_CFGDATA, r4 + + addi r3, 0, PB7CR + mtdcr EBC0_CFGADDR, r3 + addis r4, 0, CONFIG_SYS_W7O_EBC_PB7CR@h + ori r4, r4, CONFIG_SYS_W7O_EBC_PB7CR@l + mtdcr EBC0_CFGDATA, r4 + + /* We are all done */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ +.Lfe0: .size ext_bus_cntlr_init,.Lfe0-ext_bus_cntlr_init +/* end ext_bus_cntlr_init() */ + +/****************************************************************************** + * Function: sdram_init + * + * Description: Configures SDRAM memory banks. + * + * Serial Presence Detect, "SPD," reads the SDRAM EEPROM + * via the IIC bus and then configures the SDRAM memory + * banks appropriately. If Auto Memory Configuration is + * is not used, it is assumed that a 4MB 11x8x2, non-ECC, + * SDRAM is soldered down. + * + * Notes: Expects that the stack is already setup. + *****************************************************************************/ + .section ".text" + .align 2 + .globl sdram_init + .type sdram_init, @function +sdram_init: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -8(r1) /* Save back chain and move SP */ + stw r0, +12(r1) /* Save link register */ + + /* + * First call spd_sdram to try to init SDRAM according to the + * contents of the SPD EEPROM. If the SPD EEPROM is blank or + * erronious, spd_sdram returns 0 in R3. + */ + li r3,0 + bl spd_sdram + addic. r3, r3, 0 /* Check for error, save dram size */ + bne ..sdri_done /* If it worked, we're done... */ + + /******************************************************************** + * If SPD detection fails, we'll default to 4MB, 11x8x2, as this + * is the SMALLEST SDRAM size the 405 supports. We can do this + * because W7O boards have soldered on RAM, and there will always + * be some amount present. If we were using DIMMs, we should hang + * the board instead, since it doesn't have any RAM to continue + * running with. + *******************************************************************/ + + /* + * Disable memory controller to allow + * values to be changed. + */ + addi r3, 0, SDRAM0_CFG + mtdcr SDRAM0_CFGADDR, r3 + addis r4, 0, 0x0 + ori r4, r4, 0x0 + mtdcr SDRAM0_CFGDATA, r4 + + /* + * Set MB0CF for ext bank 0. (0-4MB) Address Mode 5 since 11x8x2 + * All other banks are disabled. + */ + addi r3, 0, SDRAM0_B0CR + mtdcr SDRAM0_CFGADDR, r3 + addis r4, 0, 0x0000 /* BA=0x0, SZ=4MB */ + ori r4, r4, 0x8001 /* Mode is 5, 11x8x2or4, BE=Enabled */ + mtdcr SDRAM0_CFGDATA, r4 + + /* Clear MB1CR,MB2CR,MB3CR to turn other banks off */ + addi r4, 0, 0 /* Zero the data reg */ + + addi r3, r3, 4 /* Point to MB1CF reg */ + mtdcr SDRAM0_CFGADDR, r3 /* Set the address */ + mtdcr SDRAM0_CFGDATA, r4 /* Zero the reg */ + + addi r3, r3, 4 /* Point to MB2CF reg */ + mtdcr SDRAM0_CFGADDR, r3 /* Set the address */ + mtdcr SDRAM0_CFGDATA, r4 /* Zero the reg */ + + addi r3, r3, 4 /* Point to MB3CF reg */ + mtdcr SDRAM0_CFGADDR, r3 /* Set the address */ + mtdcr SDRAM0_CFGDATA, r4 /* Zero the reg */ + + /******************************************************************** + * Set the SDRAM Timing reg, SDTR1 and the refresh timer reg, RTR. + * To set the appropriate timings, we assume sdram is + * 100MHz (pc100 compliant). + *******************************************************************/ + + /* + * Set up SDTR1 + */ + addi r3, 0, SDRAM0_TR + mtdcr SDRAM0_CFGADDR, r3 + addis r4, 0, 0x0086 /* SDTR1 value for 100Mhz */ + ori r4, r4, 0x400D + mtdcr SDRAM0_CFGDATA, r4 + + /* + * Set RTR + */ + addi r3, 0, SDRAM0_RTR + mtdcr SDRAM0_CFGADDR, r3 + addis r4, 0, 0x05F0 /* RTR refresh val = 15.625ms@100Mhz */ + mtdcr SDRAM0_CFGDATA, r4 + + /******************************************************************** + * Delay to ensure 200usec have elapsed since reset. Assume worst + * case that the core is running 200Mhz: + * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles + *******************************************************************/ + addis r3, 0, 0x0000 + ori r3, r3, 0xA000 /* Wait 200us from reset */ + mtctr r3 +..spinlp2: + bdnz ..spinlp2 /* spin loop */ + + /******************************************************************** + * Set memory controller options reg, MCOPT1. + *******************************************************************/ + addi r3, 0, SDRAM0_CFG + mtdcr SDRAM0_CFGADDR, r3 + addis r4, 0, 0x80E0 /* DC_EN=1,SRE=0,PME=0,MEMCHK=0 */ + ori r4, r4, 0x0000 /* REGEN=0,DRW=00,BRPF=01,ECCDD=1 */ + mtdcr SDRAM0_CFGDATA, r4 /* EMDULR=1 */ + +..sdri_done: + /* restore and return */ + lwz r0, +12(r1) /* Get saved link register */ + addi r1, r1, +8 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ +.Lfe1: .size sdram_init,.Lfe1-sdram_init +/* end sdram_init() */ diff --git a/qemu/roms/u-boot/board/w7o/post1.S b/qemu/roms/u-boot/board/w7o/post1.S new file mode 100644 index 000000000..aae538721 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/post1.S @@ -0,0 +1,724 @@ +/* + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net + * and + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/* + * Description: + * Routine to exercise memory for the bringing up of our boards. + */ +#include <config.h> +#include <asm/ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + +#include <watchdog.h> + +#include "errors.h" + +#define _ASMLANGUAGE + + .globl test_sdram + .globl test_led + .globl log_stat + .globl log_warn + .globl log_err + .globl temp_uart_init + .globl post_puts + .globl disp_hex + +/***************************************************** +******* Text Strings for low level printing ****** +******* In section got2 ******* +*****************************************************/ + +/* + * Define the text strings for errors and warnings. + * Switch to .data section. + */ + .section ".data" +err_str: .asciz "*** POST ERROR = " +warn_str: .asciz "*** POST WARNING = " +end_str: .asciz "\r\n" + +/* + * Enter the labels in Global Entry Table (GOT). + * Switch to .got2 section. + */ + START_GOT + GOT_ENTRY(err_str) + GOT_ENTRY(warn_str) + GOT_ENTRY(end_str) + END_GOT + +/* + * Switch back to .text section. + */ + .text + +/**************************************** + **************************************** + ******** LED register test ******** + **************************************** + ***************************************/ +test_led: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r4, +8(r1) /* save R4 */ + + WATCHDOG_RESET /* Reset the watchdog */ + + addi r3, 0, ERR_FF /* first test value is ffff */ + addi r4, r3, 0 /* save copy of pattern */ + bl set_led /* store first test value */ + bl get_led /* read it back */ + xor. r4, r4, r3 /* compare to original */ +#if defined(CONFIG_W7OLMC) + andi. r4, r4, 0x00ff /* lmc has 8 bits */ +#else + andi. r4, r4, 0xffff /* lmg has 16 bits */ +#endif + beq LED2 /* next test */ + addi r3, 0, ERR_LED /* error code = 1 */ + bl log_err /* display error and halt */ +LED2: addi r3, 0, ERR_00 /* 2nd test value is 0000 */ + addi r4, r3, 0 /* save copy of pattern */ + bl set_led /* store first test value */ + bl get_led /* read it back */ + xor. r4, r4, r3 /* compare to original */ +#if defined(CONFIG_W7OLMC) + andi. r4, r4, 0x00ff /* lmc has 8 bits */ +#else + andi. r4, r4, 0xffff /* lmg has 16 bits */ +#endif + beq LED3 /* next test */ + addi r3, 0, ERR_LED /* error code = 1 */ + bl log_err /* display error and halt */ + +LED3: /* restore stack and return */ + lwz r0, +16(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + lwz r4, +8(r1) /* restore r4 */ + addi r1, r1, +12 /* Remove frame from stack */ + blr /* Return to calling function */ + +/**************************************** + **************************************** + ******** SDRAM TESTS ******** + **************************************** + ***************************************/ +test_sdram: + /* called with mem size in r3 */ + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -16(r1) /* Save back chain and move SP */ + stw r0, +20(r1) /* Save link register */ + stmw r30, +8(r1) /* save R30,R31 */ + /* r30 is log2(mem size) */ + /* r31 is mem size */ + + /* take log2 of total mem size */ + addi r31, r3, 0 /* save total mem size */ + addi r30, 0, 0 /* clear r30 */ +l2_loop: + srwi. r31, r31, 1 /* shift right 1 */ + addi r30, r30, 1 /* count shifts */ + bne l2_loop /* loop till done */ + addi r30, r30, -1 /* correct for over count */ + addi r31, r3, 0 /* save original size */ + + /* now kick the dog and test the mem */ + WATCHDOG_RESET /* Reset the watchdog */ + bl Data_Buster /* test crossed/shorted data lines */ + addi r3, r30, 0 /* get log2(memsize) */ + addi r4, r31, 0 /* get memsize */ + bl Ghost_Buster /* test crossed/shorted addr lines */ + addi r3, r31, 0 /* get mem size */ + bl Bit_Buster /* check for bad internal bits */ + + /* restore stack and return */ + lmw r30, +8(r1) /* Restore r30, r31 */ + lwz r0, +20(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + addi r1, r1, +16 /* Remove frame from stack */ + blr /* Return to calling function */ + + +/**************************************** + ******** sdram data bus test ******** + ***************************************/ +Data_Buster: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -24(r1) /* Save back chain and move SP */ + stw r0, +28(r1) /* Save link register */ + stmw r28, 8(r1) /* save r28 - r31 on stack */ + /* r31 i/o register */ + /* r30 sdram base address */ + /* r29 5555 syndrom */ + /* r28 aaaa syndrom */ + + /* set up led register for this test */ + addi r3, 0, ERR_RAMG /* set led code to 1 */ + bl log_stat /* store test value */ + /* now test the dram data bus */ + xor r30, r30, r30 /* load r30 with base addr of sdram */ + addis r31, 0, 0x5555 /* load r31 with test value */ + ori r31, r31, 0x5555 + stw r31,0(r30) /* sto the value */ + lwz r29,0(r30) /* read it back */ + xor r29,r31,r29 /* compare it to original */ + addis r31, 0, 0xaaaa /* load r31 with test value */ + ori r31, r31, 0xaaaa + stw r31,0(r30) /* sto the value */ + lwz r28,0(r30) /* read it back */ + xor r28,r31,r28 /* compare it to original */ + or r3,r28,r29 /* or together both error terms */ + /* + * Now that we have the error bits, + * we have to decide which part they are in. + */ + bl get_idx /* r5 is now index to error */ + addi r3, r3, ERR_RAMG + cmpwi r3, ERR_RAMG /* check for errors */ + beq db_done /* skip if no errors */ + bl log_err /* log the error */ + +db_done: + lmw r28, 8(r1) /* restore r28 - r31 from stack */ + lwz r0, +28(r1) /* Get saved link register */ + addi r1, r1, +24 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + + +/**************************************************** + ******** test for address ghosting in dram ******** + ***************************************************/ + +Ghost_Buster: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -36(r1) /* Save back chain and move SP */ + stw r0, +40(r1) /* Save link register */ + stmw r25, 8(r1) /* save r25 - r31 on stack */ + /* r31 = scratch register */ + /* r30 is main referance loop counter, + 0 to 23 */ + /* r29 is ghost loop count, 0 to 22 */ + /* r28 is referance address */ + /* r27 is ghost address */ + /* r26 is log2 (mem size) = + number of byte addr bits */ + /* r25 is mem size */ + + /* save the log2(mem size) and mem size */ + addi r26, r3, 0 /* r26 is number of byte addr bits */ + addi r25, r4, 0 /* r25 is mem size in bytes */ + + /* set the leds for address ghost test */ + addi r3, 0, ERR_ADDG + bl set_led + + /* first fill memory with zeros */ + srwi r31, r25, 2 /* convert bytes to longs */ + mtctr r31 /* setup byte counter */ + addi r28, 0, 0 /* start at address at 0 */ + addi r31, 0, 0 /* data value = 0 */ +clr_loop: + stw r31, 0(r28) /* Store zero value */ + addi r28, r28, 4 /* Increment to next word */ + andi. r27, r28, 0xffff /* check for 2^16 loops */ + bne clr_skip /* if not there, then skip */ + WATCHDOG_RESET /* kick the dog every now and then */ +clr_skip: + bdnz clr_loop /* Round and round... */ + + /* now do main test */ + addi r30, 0, 0 /* start referance counter at 0 */ +outside: + /* + * Calculate the referance address + * the referance address is calculated by setting the (r30-1) + * bit of the base address + * when r30=0, the referance address is the base address. + * thus the sequence 0,1,2,4,8,..,2^(n-1) + * setting the bit is done with the following shift functions. + */ + WATCHDOG_RESET /* Reset the watchdog */ + + addi r31, 0, 1 /* r31 = 1 */ + slw r28, r31, r30 /* set bit coresponding to loop cnt */ + srwi r28, r28, 1 /* then shift it right one so */ + /* we start at location 0 */ + /* fill referance address with Fs */ + addi r31, 0, 0x00ff /* r31 = one byte of set bits */ + stb r31,0(r28) /* save ff in referance address */ + + /* ghost (inner) loop, now check all posible ghosted addresses */ + addi r29, 0, 0 /* start ghosted loop counter at 0 */ +inside: + /* + * Calculate the ghost address by flipping one + * bit of referance address. This gives the + * sequence 1,2,4,8,...,2^(n-1) + */ + addi r31, 0, 1 /* r31 = 1 */ + slw r27, r31, r29 /* set bit coresponding to loop cnt */ + xor r27, r28, r27 /* ghost address = ref addr with + bit flipped*/ + + /* now check for ghosting */ + lbz r31,0(r27) /* get content of ghost addr */ + cmpwi r31, 0 /* compare read value to 0 */ + bne Casper /* we found a ghost! */ + + /* now close ghost ( inner ) loop */ + addi r29, r29, 1 /* increment inner loop counter */ + cmpw r29, r26 /* check for last inner loop */ + blt inside /* do more inner loops */ + + /* now close referance ( outer ) loop */ + addi r31, 0, 0 /* r31 = zero */ + stb r31, 0(28) /* zero out the altered address loc. */ + /* + * Increment and check for end, count is zero based. + * With the ble, this gives us one more loops than + * address bits for sequence 0,1,2,4,8,...2^(n-1) + */ + addi r30, r30, 1 /* increment outer loop counter */ + cmpw r30, r26 /* check for last inner loop */ + ble outside /* do more outer loops */ + + /* were done, lets go home */ + b gb_done +Casper: /* we found a ghost !! */ + addi r3, 0, ERR_ADDF /* get indexed error message */ + bl log_err /* log error led error code */ +gb_done: /* pack your bags, and go home */ + lmw r25, 8(r1) /* restore r25 - r31 from stack */ + lwz r0, +40(r1) /* Get saved link register */ + addi r1, r1, +36 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + +/**************************************************** + ******** SDRAM data fill tests ********** + ***************************************************/ +Bit_Buster: + /* called with mem size in r3 */ + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -16(r1) /* Save back chain and move SP */ + stw r0, +20(r1) /* Save link register */ + stw r4, +8(r1) /* save R4 */ + stw r5, +12(r1) /* save r5 */ + + addis r5, r3, 0 /* save mem size */ + + /* Test 55555555 */ + addi r3, 0, ERR_R55G /* set up error code in case we fail */ + bl log_stat /* store test value */ + addis r4, 0, 0x5555 + ori r4, r4, 0x5555 + bl fill_test + + /* Test aaaaaaaa */ + addi r3, 0, ERR_RAAG /* set up error code in case we fail */ + bl log_stat /* store test value */ + addis r4, 0, 0xAAAA + ori r4, r4, 0xAAAA + bl fill_test + + /* Test 00000000 */ + addi r3, 0, ERR_R00G /* set up error code in case we fail */ + bl log_stat /* store test value */ + addis r4, 0, 0 + ori r4, r4, 0 + bl fill_test + + /* restore stack and return */ + lwz r5, +12(r1) /* restore r4 */ + lwz r4, +8(r1) /* restore r4 */ + lwz r0, +20(r1) /* Get saved link register */ + addi r1, r1, +16 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + + +/**************************************************** + ******** fill test ******** + ***************************************************/ +/* tests memory by filling with value, and reading back */ +/* r5 = Size of memory in bytes */ +/* r4 = Value to write */ +/* r3 = Error code */ +fill_test: + mflr r0 /* Get link register */ + stwu r1, -32(r1) /* Save back chain and move SP */ + stw r0, +36(r1) /* Save link register */ + stmw r27, 8(r1) /* save r27 - r31 on stack */ + /* r31 - scratch register */ + /* r30 - memory address */ + mr r27, r3 + mr r28, r4 + mr r29, r5 + + WATCHDOG_RESET /* Reset the watchdog */ + + /* first fill memory with Value */ + srawi r31, r29, 2 /* convert bytes to longs */ + mtctr r31 /* setup counter */ + addi r30, 0, 0 /* Make r30 = addr 0 */ +ft_0: stw r28, 0(r30) /* Store value */ + addi r30, r30, 4 /* Increment to next word */ + andi. r31, r30, 0xffff /* check for 2^16 loops */ + bne ft_0a /* if not there, then skip */ + WATCHDOG_RESET /* kick the dog every now and then */ +ft_0a: bdnz ft_0 /* Round and round... */ + + WATCHDOG_RESET /* Reset the watchdog */ + + /* Now confirm Value is in memory */ + srawi r31, r29, 2 /* convert bytes to longs */ + mtctr r31 /* setup counter */ + addi r30, 0, 0 /* Make r30 = addr 0 */ +ft_1: lwz r31, 0(r30) /* get value from memory */ + xor. r31, r31, r28 /* Writen = Read ? */ + bne ft_err /* If bad, than halt */ + addi r30, r30, 4 /* Increment to next word */ + andi. r31, r30, 0xffff /* check for 2^16 loops*/ + bne ft_1a /* if not there, then skip */ + WATCHDOG_RESET /* kick the dog every now and then */ +ft_1a: bdnz ft_1 /* Round and round... */ + + WATCHDOG_RESET /* Reset the watchdog */ + + b fill_done /* restore and return */ + +ft_err: addi r29, r27, 0 /* save current led code */ + addi r27, r31, 0 /* get pattern in r27 */ + bl get_idx /* get index from r27 */ + add r27, r27, r29 /* add index to old led code */ + bl log_err /* output led err code, halt CPU */ + +fill_done: + lmw r27, 8(r1) /* restore r27 - r31 from stack */ + lwz r0, +36(r1) /* Get saved link register */ + addi r1, r1, +32 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + + +/**************************************************** + ******* get error index from r3 pattern ******** + ***************************************************/ +get_idx: /* r3 = (MSW(r3) !=0)*2 + + (LSW(r3) !=0) */ + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r4, +8(r1) /* save R4 */ + + andi. r4, r3, 0xffff /* check for lower bits */ + beq gi2 /* skip if no bits set */ + andis. r4, r3, 0xffff /* check for upper bits */ + beq gi3 /* skip if no bits set */ + addi r3, 0, 3 /* both upper and lower bits set */ + b gi_done +gi2: andis. r4, r3, 0xffff /* check for upper bits*/ + beq gi4 /* skip if no bits set */ + addi r3, 0, 2 /* only upper bits set */ + b gi_done +gi3: addi r3, 0, 1 /* only lower bits set */ + b gi_done +gi4: addi r3, 0, 0 /* no bits set */ +gi_done: + /* restore stack and return */ + lwz r0, +16(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + lwz r4, +8(r1) /* restore r4 */ + addi r1, r1, +12 /* Remove frame from stack */ + blr /* Return to calling function */ + +/**************************************************** + ******** set LED to R5 and hang ******** + ***************************************************/ +log_stat: /* output a led code and continue */ +set_led: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r4, +8(r1) /* save R4 */ + + addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */ +#if defined(CONFIG_W7OLMG) /* only on gateway, invert outputs */ + xori r3,r3, 0xffff /* complement led code, active low */ + sth r3, 0(r4) /* store first test value */ + xori r3,r3, 0xffff /* complement led code, active low */ +#else /* if not gateway, then don't invert */ + sth r3, 0(r4) /* store first test value */ +#endif + + /* restore stack and return */ + lwz r0, +16(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + lwz r4, +8(r1) /* restore r4 */ + addi r1, r1, +12 /* Remove frame from stack */ + blr /* Return to calling function */ + +get_led: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r4, +8(r1) /* save R4 */ + + addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */ + lhz r3, 0(r4) /* store first test value */ +#if defined(CONFIG_W7OLMG) /* only on gateway, invert inputs */ + xori r3,r3, 0xffff /* complement led code, active low */ +#endif + + /* restore stack and return */ + lwz r0, +16(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + lwz r4, +8(r1) /* restore r4 */ + addi r1, r1, +12 /* Remove frame from stack */ + blr /* Return to calling function */ + +log_err: /* output the error and hang the board ( for now ) */ + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r3, +8(r1) /* save a copy of error code */ + bl set_led /* set the led pattern */ + GET_GOT /* get GOT address in r14 */ + lwz r3,GOT(err_str) /* get address of string */ + bl post_puts /* output the warning string */ + lwz r3, +8(r1) /* get error code */ + addi r4, 0, 2 /* set disp length to 2 nibbles */ + bl disp_hex /* output the error code */ + lwz r3,GOT(end_str) /* get address of string */ + bl post_puts /* output the warning string */ +halt: + b halt /* hang */ + + /* restore stack and return */ + lwz r0, +16(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + addi r1, r1, +12 /* Remove frame from stack */ + blr /* Return to calling function */ + +log_warn: /* output a warning, then continue with operations */ + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -16(r1) /* Save back chain and move SP */ + stw r0, +20(r1) /* Save link register */ + stw r3, +8(r1) /* save a copy of error code */ + stw r14, +12(r1) /* save a copy of r14 (used by GOT) */ + + bl set_led /* set the led pattern */ + GET_GOT /* get GOT address in r14 */ + lwz r3,GOT(warn_str) /* get address of string */ + bl post_puts /* output the warning string */ + lwz r3, +8(r1) /* get error code */ + addi r4, 0, 2 /* set disp length to 2 nibbles */ + bl disp_hex /* output the error code */ + lwz r3,GOT(end_str) /* get address of string */ + bl post_puts /* output the warning string */ + + addis r3, 0, 64 /* has a long delay */ + mtctr r3 +log_2: + WATCHDOG_RESET /* this keeps dog from barking, */ + /* and takes time */ + bdnz log_2 /* loop till time expires */ + + /* restore stack and return */ + lwz r0, +20(r1) /* Get saved link register */ + lwz r14, +12(r1) /* restore r14 */ + mtlr r0 /* Restore link register */ + addi r1, r1, +16 /* Remove frame from stack */ + blr /* Return to calling function */ + +/******************************************************************* + * temp_uart_init + * Temporary UART initialization routine + * Sets up UART0 to run at 9600N81 off of the internal clock. + * R3-R4 are used. + ******************************************************************/ +temp_uart_init: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -8(r1) /* Save back chain and move SP */ + stw r0, +12(r1) /* Save link register */ + + addis r3, 0, 0xef60 + ori r3, r3, 0x0303 /* r3 = UART0_LCR */ + addi r4, 0, 0x83 /* n81 format, divisor regs enabled */ + stb r4, 0(r3) + + /* set baud rate to use internal clock, + baud = (200e6/16)/31/42 = 9600 */ + + addis r3, 0, 0xef60 /* Address of baud divisor reg */ + ori r3, r3, 0x0300 /* UART0_DLM */ + addi r4, 0, +42 /* uart baud divisor LSB = 93 */ + stb r4, 0(r3) /* baud = (200 /16)/14/93 */ + + addi r3, r3, 0x0001 /* uart baud divisor addr */ + addi r4, 0, 0 + stb r4, 0(r3) /* Divisor Latch MSB = 0 */ + + addis r3, 0, 0xef60 + ori r3, r3, 0x0303 /* r3 = UART0_LCR */ + addi r4, 0, 0x03 /* n81 format, tx/rx regs enabled */ + stb r4, 0(r3) + + /* output a few line feeds */ + addi r3, 0, '\n' /* load line feed */ + bl post_putc /* output the char */ + addi r3, 0, '\n' /* load line feed */ + bl post_putc /* output the char */ + + /* restore stack and return */ + lwz r0, +12(r1) /* Get saved link register */ + mtlr r0 /* Restore link register */ + addi r1, r1, +8 /* Remove frame from stack */ + blr /* Return to calling function */ + +/********************************************************************** + ** post_putc + ** outputs charactor in R3 + ** r3 returns the error code ( -1 if there is an error ) + *********************************************************************/ + +post_putc: + + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -20(r1) /* Save back chain and move SP */ + stw r0, +24(r1) /* Save link register */ + stmw r29, 8(r1) /* save r29 - r31 on stack + r31 - uart base address + r30 - delay counter + r29 - scratch reg */ + + addis r31, 0, 0xef60 /* Point to uart base */ + ori r31, r31, 0x0300 + addis r30, 0, 152 /* Load about 10,000,000 ticks. */ +pputc_lp: + lbz r29, 5(r31) /* Read Line Status Register */ + andi. r29, r29, 0x20 /* Check THRE status */ + bne thre_set /* Branch if FIFO empty */ + addic. r30, r30, -1 /* Decrement and check if empty. */ + bne pputc_lp /* Try, try again */ + addi r3, 0, -1 /* Load error code for timeout */ + b pputc_done /* Bail out with error code set */ +thre_set: + stb r3, 0(r31) /* Store character to UART */ + addi r3, 0, 0 /* clear error code */ +pputc_done: + lmw r29, 8(r1) /*restore r29 - r31 from stack */ + lwz r0, +24(r1) /* Get saved link register */ + addi r1, r1, +20 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + + +/**************************************************************** + post_puts + Accepts a null-terminated string pointed to by R3 + Outputs to the serial port until 0x00 is found. + r3 returns the error code ( -1 if there is an error ) +*****************************************************************/ +post_puts: + + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -12(r1) /* Save back chain and move SP */ + stw r0, +16(r1) /* Save link register */ + stw r31, 8(r1) /* save r31 - char pointer */ + + addi r31, r3, 0 /* move pointer to R31 */ +pputs_nxt: + lbz r3, 0(r31) /* Get next character */ + addic. r3, r3, 0 /* Check for zero */ + beq pputs_term /* bail out if zero */ + bl post_putc /* output the char */ + addic. r3, r3, 0 /* check for error */ + bne pputs_err + addi r31, r31, 1 /* point to next char */ + b pputs_nxt /* loop till term */ +pputs_err: + addi r3, 0, -1 /* set error code */ + b pputs_end /* were outa here */ +pputs_term: + addi r3, 0, 1 /* set success code */ + /* restore stack and return */ +pputs_end: + lwz r31, 8(r1) /* restore r27 - r31 from stack */ + lwz r0, +16(r1) /* Get saved link register */ + addi r1, r1, +12 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ + + +/******************************************************************** + ***** disp_hex + ***** Routine to display a hex value from a register. + ***** R3 is value to display + ***** R4 is number of nibbles to display ie 2 for byte 8 for (long)word + ***** Returns -1 in R3 if there is an error ( ie serial port hangs ) + ***** Returns 0 in R3 if no error + *******************************************************************/ +disp_hex: + /* save the return info on stack */ + mflr r0 /* Get link register */ + stwu r1, -16(r1) /* Save back chain and move SP */ + stw r0, +20(r1) /* Save link register */ + stmw r30, 8(r1) /* save r30 - r31 on stack */ + /* r31 output char */ + /* r30 uart base address */ + addi r30, 0, 8 /* Go through 8 nibbles. */ + addi r31, r3, 0 +pputh_nxt: + rlwinm r31, r31, 4, 0, 31 /* Rotate next nibble into position */ + andi. r3, r31, 0x0f /* Get nibble. */ + addi r3, r3, 0x30 /* Add zero's ASCII code. */ + cmpwi r3, 0x03a + blt pputh_out + addi r3, r3, 0x07 /* 0x27 for lower case. */ +pputh_out: + cmpw r30, r4 + bgt pputh_skip + bl post_putc + addic. r3, r3, 0 /* check for error */ + bne pputh_err +pputh_skip: + addic. r30, r30, -1 + bne pputh_nxt + xor r3, r3, r3 /* Clear error code */ + b pputh_done +pputh_err: + addi r3, 0, -1 /* set error code */ +pputh_done: + /* restore stack and return */ + lmw r30, 8(r1) /* restore r30 - r31 from stack */ + lwz r0, +20(r1) /* Get saved link register */ + addi r1, r1, +16 /* Remove frame from stack */ + mtlr r0 /* Restore link register */ + blr /* Return to calling function */ diff --git a/qemu/roms/u-boot/board/w7o/post2.c b/qemu/roms/u-boot/board/w7o/post2.c new file mode 100644 index 000000000..76b65975c --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/post2.c @@ -0,0 +1,98 @@ +/* + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net + * and + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <rtc.h> +#include "errors.h" +#include "dtt.h" + +/* for LM75 DTT POST test */ +#define DTT_READ_TEMP 0x0 +#define DTT_CONFIG 0x1 +#define DTT_TEMP_HYST 0x2 +#define DTT_TEMP_SET 0x3 + +#if defined(CONFIG_RTC_M48T35A) +void rtctest(void) +{ + volatile uchar *tchar = (uchar*)(CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE - 9); + struct rtc_time tmp; + + /* set up led code for RTC tests */ + log_stat(ERR_RTCG); + + /* + * Do RTC battery test. The first write after power up + * fails if battery is low. + */ + *tchar = 0xaa; + if ((*tchar ^ 0xaa) != 0x0) log_warn(ERR_RTCBAT); + *tchar = 0x55; /* Reset test address */ + + /* + * Now lets check the validity of the values in the RTC. + */ + rtc_get(&tmp); + if ((tmp.tm_sec < 0) | (tmp.tm_sec > 59) | + (tmp.tm_min < 0) | (tmp.tm_min > 59) | + (tmp.tm_hour < 0) | (tmp.tm_hour > 23) | + (tmp.tm_mday < 1 ) | (tmp.tm_mday > 31) | + (tmp.tm_mon < 1 ) | (tmp.tm_mon > 12) | + (tmp.tm_year < 2000) | (tmp.tm_year > 2500) | + (tmp.tm_wday < 1 ) | (tmp.tm_wday > 7)) { + log_warn(ERR_RTCTIM); + rtc_reset(); + } + + /* + * Now lets do a check to see if the NV RAM is there. + */ + *tchar = 0xaa; + if ((*tchar ^ 0xaa) != 0x0) log_err(ERR_RTCVAL); + *tchar = 0x55; /* Reset test address */ + +} /* rtctest() */ +#endif /* CONFIG_RTC_M48T35A */ + + +#ifdef CONFIG_DTT_LM75 +int dtt_test(int sensor) +{ + short temp, trip, hyst; + + /* get values */ + temp = dtt_read(sensor, DTT_READ_TEMP) / 256; + trip = dtt_read(sensor, DTT_TEMP_SET) / 256; + hyst = dtt_read(sensor, DTT_TEMP_HYST) / 256; + + /* check values */ + if ((hyst != (CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS)) || + (trip != CONFIG_SYS_DTT_MAX_TEMP) || + (temp < CONFIG_SYS_DTT_LOW_TEMP) || (temp > CONFIG_SYS_DTT_MAX_TEMP)) + return 1; + + return 0; +} /* dtt_test() */ +#endif /* CONFIG_DTT_LM75 */ + +/*****************************************/ + +void post2(void) +{ +#if defined(CONFIG_RTC_M48T35A) + rtctest(); +#endif /* CONFIG_RTC_M48T35A */ + +#ifdef CONFIG_DTT_LM75 + log_stat(ERR_TempG); + if(dtt_test(2) != 0) log_warn(ERR_Ttest0); + if(dtt_test(4) != 0) log_warn(ERR_Ttest1); +#endif /* CONFIG_DTT_LM75 */ +} /* post2() */ diff --git a/qemu/roms/u-boot/board/w7o/u-boot.lds.debug b/qemu/roms/u-boot/board/w7o/u-boot.lds.debug new file mode 100644 index 000000000..5740efb7e --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/u-boot.lds.debug @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + mpc8xx/start.o (.text) + common/dlmalloc.o (.text) + lib/vsprintf.o (.text) + lib/crc32.o (.text) + arch/powerpc/lib/extable.o (.text) + + common/env_embedded.o(.text) + + *(.text) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + __bss_end = . ; + PROVIDE (end = .); +} diff --git a/qemu/roms/u-boot/board/w7o/vpd.c b/qemu/roms/u-boot/board/w7o/vpd.c new file mode 100644 index 000000000..fbcc3944d --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/vpd.c @@ -0,0 +1,412 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#if defined(VXWORKS) +#include <stdio.h> +#include <string.h> +#define CONFIG_SYS_DEF_EEPROM_ADDR 0xa0 +extern char iicReadByte(char, char); +extern ulong_t crc32(unsigned char *, unsigned long); +#else +#include <common.h> +#endif + +#include "vpd.h" + +/* + * vpd_reader() - reads VPD data from I2C EEPROMS. + * returns pointer to buffer or NULL. + */ +static unsigned char *vpd_reader(unsigned char *buf, unsigned dev_addr, + unsigned off, unsigned count) +{ + unsigned offset = off; /* Calculated offset */ + + /* + * The main board EEPROM contains + * SDRAM SPD in the first 128 bytes, + * so skew the offset. + */ + if (dev_addr == CONFIG_SYS_DEF_EEPROM_ADDR) + offset += SDRAM_SPD_DATA_SIZE; + + /* Try to read the I2C EEPROM */ +#if defined(VXWORKS) + { + int i; + + for (i = 0; i < count; ++i) + buf[i] = iicReadByte(dev_addr, offset + i); + } +#else + if (eeprom_read(dev_addr, offset, buf, count)) { + printf("Failed to read %d bytes from VPD EEPROM 0x%x @ 0x%x\n", + count, dev_addr, offset); + return NULL; + } +#endif + + return buf; +} + + +/* + * vpd_get_packet() - returns next VPD packet or NULL. + */ +static vpd_packet_t *vpd_get_packet(vpd_packet_t * vpd_packet) +{ + vpd_packet_t *packet = vpd_packet; + + if (packet != NULL) { + if (packet->identifier == VPD_PID_TERM) + return NULL; + else + packet = (vpd_packet_t *) ((char *) packet + + packet->size + 2); + } + + return packet; +} + + +/* + * vpd_find_packet() - Locates and returns the specified + * VPD packet or NULL on error. + */ +static vpd_packet_t *vpd_find_packet(vpd_t * vpd, unsigned char ident) +{ + vpd_packet_t *packet = (vpd_packet_t *) &vpd->packets; + + /* Guaranteed illegal */ + if (ident == VPD_PID_GI) + return NULL; + + /* Scan tuples looking for a match */ + while ((packet->identifier != ident) && + (packet->identifier != VPD_PID_TERM)) + packet = vpd_get_packet(packet); + + /* Did we find it? */ + if ((packet->identifier) && (packet->identifier != ident)) + return NULL; + return packet; +} + + +/* + * vpd_is_valid() - Validates contents of VPD data + * in I2C EEPROM. Returns 1 for + * success or 0 for failure. + */ +static int vpd_is_valid(unsigned dev_addr, unsigned char *buf) +{ + unsigned num_bytes; + vpd_packet_t *packet; + vpd_t *vpd = (vpd_t *) buf; + unsigned short stored_crc16, calc_crc16 = 0xffff; + + /* Check Eyecatcher */ + if (strncmp + ((char *) (vpd->header.eyecatcher), VPD_EYECATCHER, + VPD_EYE_SIZE) != 0) { + unsigned offset = 0; + + if (dev_addr == CONFIG_SYS_DEF_EEPROM_ADDR) + offset += SDRAM_SPD_DATA_SIZE; + printf("Error: VPD EEPROM 0x%x corrupt @ 0x%x\n", dev_addr, + offset); + + return 0; + } + + /* Check Length */ + if (vpd->header.size > VPD_MAX_EEPROM_SIZE) { + printf("Error: VPD EEPROM 0x%x contains bad size 0x%x\n", + dev_addr, vpd->header.size); + return 0; + } + + /* Now find the termination packet */ + packet = vpd_find_packet(vpd, VPD_PID_TERM); + if (packet == NULL) { + printf("Error: VPD EEPROM 0x%x missing termination packet\n", + dev_addr); + return 0; + } + + /* Calculate data size */ + num_bytes = (unsigned long) ((unsigned char *) packet - + (unsigned char *) vpd + + sizeof(vpd_packet_t)); + + /* Find stored CRC and clear it */ + packet = vpd_find_packet(vpd, VPD_PID_CRC); + if (packet == NULL) { + printf("Error: VPD EEPROM 0x%x missing CRC\n", dev_addr); + return 0; + } + memcpy(&stored_crc16, packet->data, sizeof(ushort)); + memset(packet->data, 0, sizeof(ushort)); + + /* OK, lets calculate the CRC and check it */ +#if defined(VXWORKS) + calc_crc16 = (0xffff & crc32(buf, num_bytes)); +#else + calc_crc16 = (0xffff & crc32(0, buf, num_bytes)); +#endif + /* Now restore the CRC */ + memcpy(packet->data, &stored_crc16, sizeof(ushort)); + if (stored_crc16 != calc_crc16) { + printf("Error: VPD EEPROM 0x%x has bad CRC 0x%x\n", + dev_addr, stored_crc16); + return 0; + } + + return 1; +} + + +/* + * size_ok() - Check to see if packet size matches + * size of data we want. Returns 1 for + * good match or 0 for failure. + */ +static int size_ok(vpd_packet_t *packet, unsigned long size) +{ + if (packet->size != size) { + printf("VPD Packet 0x%x corrupt.\n", packet->identifier); + return 0; + } + return 1; +} + + +/* + * strlen_ok() - Check to see if packet size matches + * strlen of the string we want to populate. + * Returns 1 for valid length or 0 for failure. + */ +static int strlen_ok(vpd_packet_t *packet, unsigned long length) +{ + if (packet->size >= length) { + printf("VPD Packet 0x%x corrupt.\n", packet->identifier); + return 0; + } + return 1; +} + + +/* + * get_vpd_data() - populates the passed VPD structure 'vpdInfo' + * with data obtained from the specified + * I2C EEPROM 'dev_addr'. Returns 0 for + * success or 1 for failure. + */ +int vpd_get_data(unsigned char dev_addr, VPD *vpdInfo) +{ + unsigned char buf[VPD_EEPROM_SIZE]; + vpd_t *vpd = (vpd_t *) buf; + vpd_packet_t *packet; + + if (vpdInfo == NULL) + return 1; + + /* + * Fill vpdInfo with 0s to blank out + * unused fields, fill vpdInfo->ethAddrs + * with all 0xffs so that other's code can + * determine how many real Ethernet addresses + * there are. OUIs starting with 0xff are + * broadcast addresses, and would never be + * permantely stored. + */ + memset((void *) vpdInfo, 0, sizeof(VPD)); + memset((void *) &vpdInfo->ethAddrs, 0xff, sizeof(vpdInfo->ethAddrs)); + vpdInfo->_devAddr = dev_addr; + + /* Read the minimum size first */ + if (vpd_reader(buf, dev_addr, 0, VPD_EEPROM_SIZE) == NULL) + return 1; + + /* Check validity of VPD data */ + if (!vpd_is_valid(dev_addr, buf)) { + printf("VPD Data is INVALID!\n"); + return 1; + } + + /* + * Walk all the packets and populate + * the VPD info structure. + */ + packet = (vpd_packet_t *) &vpd->packets; + do { + switch (packet->identifier) { + case VPD_PID_GI: + printf("Error: Illegal VPD value\n"); + break; + case VPD_PID_PID: + if (strlen_ok(packet, MAX_PROD_ID)) { + strncpy(vpdInfo->productId, + (char *) (packet->data), + packet->size); + } + break; + case VPD_PID_REV: + if (size_ok(packet, sizeof(char))) + vpdInfo->revisionId = *packet->data; + break; + case VPD_PID_SN: + if (size_ok(packet, sizeof(unsigned long))) { + memcpy(&vpdInfo->serialNum, + packet->data, + sizeof(unsigned long)); + } + break; + case VPD_PID_MANID: + if (size_ok(packet, sizeof(unsigned char))) + vpdInfo->manuID = *packet->data; + break; + case VPD_PID_PCO: + if (size_ok(packet, sizeof(unsigned long))) { + memcpy(&vpdInfo->configOpt, + packet->data, + sizeof(unsigned long)); + } + break; + case VPD_PID_SYSCLK: + if (size_ok(packet, sizeof(unsigned long))) + memcpy(&vpdInfo->sysClk, + packet->data, + sizeof(unsigned long)); + break; + case VPD_PID_SERCLK: + if (size_ok(packet, sizeof(unsigned long))) + memcpy(&vpdInfo->serClk, + packet->data, + sizeof(unsigned long)); + break; + case VPD_PID_FLASH: + if (size_ok(packet, 9)) { /* XXX - hardcoded, + padding in struct */ + memcpy(&vpdInfo->flashCfg, packet->data, 9); + } + break; + case VPD_PID_ETHADDR: + memcpy(vpdInfo->ethAddrs, packet->data, packet->size); + break; + case VPD_PID_POTS: + if (size_ok(packet, sizeof(char))) + vpdInfo->numPOTS = (unsigned) *packet->data; + break; + case VPD_PID_DS1: + if (size_ok(packet, sizeof(char))) + vpdInfo->numDS1 = (unsigned) *packet->data; + case VPD_PID_GAL: + case VPD_PID_CRC: + case VPD_PID_TERM: + break; + default: + printf("Warning: Found unknown VPD packet ID 0x%x\n", + packet->identifier); + break; + } + } while ((packet = vpd_get_packet(packet))); + + return 0; +} + + +/* + * vpd_init() - Initialize default VPD environment + */ +int vpd_init(unsigned char dev_addr) +{ + return 0; +} + + +/* + * vpd_print() - Pretty print the VPD data. + */ +void vpd_print(VPD *vpdInfo) +{ + const char *const sp = ""; + const char *const sfmt = "%4s%-20s: \"%s\"\n"; + const char *const cfmt = "%4s%-20s: '%c'\n"; + const char *const dfmt = "%4s%-20s: %ld\n"; + const char *const hfmt = "%4s%-20s: %08lX\n"; + const char *const dsfmt = "%4s%-20s: %d\n"; + const char *const hsfmt = "%4s%-20s: %04X\n"; + const char *const dhfmt = "%4s%-20s: %ld (%lX)\n"; + + printf("VPD read from I2C device: %02X\n", vpdInfo->_devAddr); + + if (vpdInfo->productId[0]) + printf(sfmt, sp, "Product ID", vpdInfo->productId); + else + printf(sfmt, sp, "Product ID", "UNKNOWN"); + + if (vpdInfo->revisionId) + printf(cfmt, sp, "Revision ID", vpdInfo->revisionId); + + if (vpdInfo->serialNum) + printf(dfmt, sp, "Serial Number", vpdInfo->serialNum); + + if (vpdInfo->manuID) + printf(dfmt, sp, "Manufacture ID", (long) vpdInfo->manuID); + + if (vpdInfo->configOpt) + printf(hfmt, sp, "Configuration", vpdInfo->configOpt); + + if (vpdInfo->sysClk) + printf(dhfmt, sp, "System Clock", vpdInfo->sysClk, + vpdInfo->sysClk); + + if (vpdInfo->serClk) + printf(dhfmt, sp, "Serial Clock", vpdInfo->serClk, + vpdInfo->serClk); + + if (vpdInfo->numPOTS) + printf(dfmt, sp, "Number of POTS lines", vpdInfo->numPOTS); + + if (vpdInfo->numDS1) + printf(dfmt, sp, "Number of DS1s", vpdInfo->numDS1); + + /* Print Ethernet Addresses */ + if (vpdInfo->ethAddrs[0][0] != 0xff) { + int i, j; + + printf("%4sEtherNet Address(es): ", sp); + for (i = 0; i < MAX_ETH_ADDRS; i++) { + if (vpdInfo->ethAddrs[i][0] != 0xff) { + for (j = 0; j < 6; j++) { + printf("%02X", + vpdInfo->ethAddrs[i][j]); + if (((j + 1) % 6) != 0) + printf(":"); + else + printf(" "); + } + if (((i + 1) % 3) == 0) + printf("\n%24s: ", sp); + } + } + printf("\n"); + } + + if (vpdInfo->flashCfg.mfg && vpdInfo->flashCfg.dev) { + printf("Main Flash Configuration:\n"); + printf(hsfmt, sp, "Manufacture ID", vpdInfo->flashCfg.mfg); + printf(hsfmt, sp, "Device ID", vpdInfo->flashCfg.dev); + printf(dsfmt, sp, "Device Width", vpdInfo->flashCfg.devWidth); + printf(dsfmt, sp, "Num. Devices", vpdInfo->flashCfg.numDevs); + printf(dsfmt, sp, "Num. Columns", vpdInfo->flashCfg.numCols); + printf(dsfmt, sp, "Column Width", vpdInfo->flashCfg.colWidth); + printf(dsfmt, sp, "WE Data Width", + vpdInfo->flashCfg.weDataWidth); + } +} diff --git a/qemu/roms/u-boot/board/w7o/vpd.h b/qemu/roms/u-boot/board/w7o/vpd.h new file mode 100644 index 000000000..2395b18a9 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/vpd.h @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _VPD_H_ +#define _VPD_H_ + +/* + * Main Flash Configuration. + */ +typedef struct flashCfg_s { + unsigned short mfg; /* Manufacture ID */ + unsigned short dev; /* Device ID */ + unsigned char devWidth; /* Device Width */ + unsigned char numDevs; /* Number of devices */ + unsigned char numCols; /* Number of columns */ + unsigned char colWidth; /* Width of a column */ + unsigned char weDataWidth; /* Write/Erase Data Width */ +} flashCfg_t; + +/* + * Vital Product Data - VPD + */ +#define MAX_PROD_ID 15 +#define MAX_ETH_ADDRS 10 +typedef unsigned char EthAddr[6]; +typedef struct vpd { + unsigned char _devAddr; /* Device address during read */ + char productId[MAX_PROD_ID]; /* Product ID */ + char revisionId; /* Revision ID as a char */ + unsigned long serialNum; /* Serial number */ + unsigned char manuID; /* Manufact ID - byte int */ + unsigned long configOpt; /* Config Option - bit field */ + unsigned long sysClk; /* System clock in Hertz */ + unsigned long serClk; /* Ext. clock in Hertz */ + flashCfg_t flashCfg; /* Flash configuration */ + unsigned long numPOTS; /* Number of POTS lines */ + unsigned long numDS1; /* Number of DS1 circuits */ + EthAddr ethAddrs[MAX_ETH_ADDRS]; /* Ethernet MAC, 1st = craft */ +} VPD; + + +#define VPD_MAX_EEPROM_SIZE 512 /* Max size VPD EEPROM */ +#define SDRAM_SPD_DATA_SIZE 128 /* Size SPD in VPD EEPROM */ + +/* + * PIDs - Packet Identifiers + */ +#define VPD_PID_GI 0x0 /* Guaranted Illegal */ +#define VPD_PID_PID 0x1 /* Product Identifier */ +#define VPD_PID_REV 0x2 /* Product Revision */ +#define VPD_PID_SN 0x3 /* Serial Number */ +#define VPD_PID_MANID 0x4 /* Manufacture ID */ +#define VPD_PID_PCO 0x5 /* Product configuration */ +#define VPD_PID_SYSCLK 0x6 /* System Clock */ +#define VPD_PID_SERCLK 0x7 /* Ser. Clk. Speed in Hertz */ +#define VPD_PID_CRC 0x8 /* VPD CRC */ +#define VPD_PID_FLASH 0x9 /* Flash Configuration */ +#define VPD_PID_ETHADDR 0xA /* Ethernet Address(es) */ +#define VPD_PID_GAL 0xB /* Galileo Switch Config */ +#define VPD_PID_POTS 0xC /* Number of POTS Lines */ +#define VPD_PID_DS1 0xD /* Number of DS1s */ +#define VPD_PID_TERM 0xFF /* Termination packet */ + +/* + * VPD - Eyecatcher/Magic + */ +#define VPD_EYECATCHER "W7O" +#define VPD_EYE_SIZE 3 +typedef struct vpd_header { + unsigned char eyecatcher[VPD_EYE_SIZE]; /* eyecatcher - "W7O" */ + unsigned short size __attribute__((packed)); /* size of EEPROM */ +} vpd_header_t; + + +#define VPD_DATA_SIZE (VPD_MAX_EEPROM_SIZE - SDRAM_SPD_DATA_SIZE - \ + sizeof(vpd_header_t)) +typedef struct vpd_s { + vpd_header_t header; + unsigned char packets[VPD_DATA_SIZE]; +} vpd_t; + +typedef struct vpd_packet { + unsigned char identifier; + unsigned char size; + unsigned char data[1]; +} vpd_packet_t; + +/* + * VPD configOpt bit mask + */ +#define VPD_HAS_BBRAM 0x1 /* Battery backed SRAM */ +#define VPD_HAS_RTC 0x2 /* Battery backed RTC */ +#define VPD_HAS_EXT_SER_CLK 0x4 /* External serial clock */ +#define VPD_HAS_SER_TRANS_1 0x8 /* COM1 transceiver */ +#define VPD_HAS_SER_TRANS_2 0x10 /* COM2 transceiver */ +#define VPD_HAS_CRAFT_PHY 0x20 /* CRAFT Ethernet */ +#define VPD_HAS_DTT_1 0x40 /* I2C Digital therm. #1 */ +#define VPD_HAS_DTT_2 0x80 /* I2C Digital therm. #2 */ +#define VPD_HAS_1000_UP_LASER 0x100 /* GMM - 1000Mbit Uplink */ +#define VPD_HAS_70KM_UP_LASER 0x200 /* CMM - 70KM Uplink laser */ +#define VPD_HAS_2_UPLINKS 0x400 /* CMM - 2 uplink lasers */ +#define VPD_HAS_FPGA 0x800 /* Has 1 or more FPGAs */ +#define VPD_HAS_DFA 0x1000 /* CLM - Has 2 Fiber Inter. */ +#define VPD_HAS_GAL_SWITCH 0x2000 /* GMM - Has a Gal switch */ +#define VPD_HAS_POTS_LINES 0x4000 /* GMM - Has POTS lines */ +#define VPD_HAS_DS1_CHANNELS 0x8000 /* GMM - Has DS1 channels */ +#define VPD_HAS_CABLE_RETURN 0x10000 /* GBM/GBR - Cable ret. path */ + +#define VPD_EEPROM_SIZE (256 - SDRAM_SPD_DATA_SIZE) /* Size EEPROM */ + +extern int vpd_get_data(unsigned char dev_addr, VPD *vpd); +extern void vpd_print(VPD *vpdInfo); + +#endif /* _VPD_H_ */ diff --git a/qemu/roms/u-boot/board/w7o/w7o.c b/qemu/roms/u-boot/board/w7o/w7o.c new file mode 100644 index 000000000..afbbaf58e --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/w7o.c @@ -0,0 +1,257 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include "w7o.h" +#include <asm/processor.h> + +#include "vpd.h" +#include "errors.h" +#include <watchdog.h> + +unsigned long get_dram_size (void); +void sdram_init(void); + +/* ------------------------------------------------------------------------- */ + +int board_early_init_f (void) +{ +#if defined(CONFIG_W7OLMG) + /* + * Setup GPIO pins - reset devices. + */ + out32 (PPC405GP_GPIO0_ODR, 0x10000000); /* one open drain pin */ + out32 (PPC405GP_GPIO0_OR, 0x3E000000); /* set output pins to default */ + out32 (PPC405GP_GPIO0_TCR, 0x7f800000); /* setup for output */ + + /* + * IRQ 0-15 405GP internally generated; active high; level sensitive + * IRQ 16 405GP internally generated; active low; level sensitive + * IRQ 17-24 RESERVED + * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive + * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive + * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive + * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive + * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive + * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive + * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive + */ + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + mtdcr (UIC0ER, 0x00000000); /* disable all ints */ + + mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical */ + mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */ + mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */ + mtdcr (UIC0VCR, 0x00000001); /* set vect base=0, + INT0 highest priority */ + + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + +#elif defined(CONFIG_W7OLMC) + /* + * Setup GPIO pins + */ + out32 (PPC405GP_GPIO0_ODR, 0x01800000); /* XCV Done Open Drain */ + out32 (PPC405GP_GPIO0_OR, 0x03800000); /* set out pins to default */ + out32 (PPC405GP_GPIO0_TCR, 0x66C00000); /* setup for output */ + + /* + * IRQ 0-15 405GP internally generated; active high; level sensitive + * IRQ 16 405GP internally generated; active low; level sensitive + * IRQ 17-24 RESERVED + * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive + * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive + * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive + * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive + * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive + * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive + * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive + */ + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + mtdcr (UIC0ER, 0x00000000); /* disable all ints */ + + mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical */ + mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */ + mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */ + mtdcr (UIC0VCR, 0x00000001); /* set vect base=0, + INT0 highest priority */ + + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + +#else /* Unknown */ +# error "Unknown W7O board configuration" +#endif + + WATCHDOG_RESET (); /* Reset the watchdog */ + temp_uart_init (); /* init the uart for debug */ + WATCHDOG_RESET (); /* Reset the watchdog */ + test_led (); /* test the LEDs */ + test_sdram (get_dram_size ()); /* test the dram */ + log_stat (ERR_POST1); /* log status,post1 complete */ + return 0; +} + + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ +int checkboard (void) +{ + VPD vpd; + + puts ("Board: "); + + /* VPD data present in I2C EEPROM */ + if (vpd_get_data (CONFIG_SYS_DEF_EEPROM_ADDR, &vpd) == 0) { + /* + * Known board type. + */ + if (vpd.productId[0] && + ((strncmp (vpd.productId, "GMM", 3) == 0) || + (strncmp (vpd.productId, "CMM", 3) == 0))) { + + /* Output board information on startup */ + printf ("\"%s\", revision '%c', serial# %ld, manufacturer %u\n", vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID); + return (0); + } + } + + puts ("### Unknown HW ID - assuming NOTHING\n"); + return (0); +} + +/* ------------------------------------------------------------------------- */ + +phys_size_t initdram (int board_type) +{ + /* + * ToDo: Move the asm init routine sdram_init() to this C file, + * or even better use some common ppc4xx code available + * in arch/powerpc/cpu/ppc4xx + */ + sdram_init(); + + return get_dram_size (); +} + +unsigned long get_dram_size (void) +{ + int tmp, i, regs[4]; + int size = 0; + + /* Get bank Size registers */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR); /* get bank 0 config reg */ + regs[0] = mfdcr (SDRAM0_CFGDATA); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR); /* get bank 1 config reg */ + regs[1] = mfdcr (SDRAM0_CFGDATA); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR); /* get bank 2 config reg */ + regs[2] = mfdcr (SDRAM0_CFGDATA); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR); /* get bank 3 config reg */ + regs[3] = mfdcr (SDRAM0_CFGDATA); + + /* compute the size, add each bank if enabled */ + for (i = 0; i < 4; i++) { + if (regs[i] & 0x0001) { /* if enabled, */ + tmp = ((regs[i] >> (31 - 14)) & 0x7); /* get size bits */ + tmp = 0x400000 << tmp; /* Size bits X 4MB = size */ + size += tmp; + } + } + + return size; +} + +int misc_init_f (void) +{ + return 0; +} + +static void w7o_env_init (VPD * vpd) +{ + /* + * Read VPD + */ + if (vpd_get_data (CONFIG_SYS_DEF_EEPROM_ADDR, vpd) != 0) + return; + + /* + * Known board type. + */ + if (vpd->productId[0] && + ((strncmp (vpd->productId, "GMM", 3) == 0) || + (strncmp (vpd->productId, "CMM", 3) == 0))) { + char buf[30]; + char *eth; + char *serial = getenv ("serial#"); + char *ethaddr = getenv ("ethaddr"); + + /* Set 'serial#' envvar if serial# isn't set */ + if (!serial) { + sprintf (buf, "%s-%ld", vpd->productId, + vpd->serialNum); + setenv ("serial#", buf); + } + + /* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */ + eth = (char *)(vpd->ethAddrs[0]); + if (ethaddr + && (strcmp(ethaddr, __stringify(CONFIG_ETHADDR)) == 0)) { + /* Now setup ethaddr */ + sprintf (buf, "%02x:%02x:%02x:%02x:%02x:%02x", + eth[0], eth[1], eth[2], eth[3], eth[4], + eth[5]); + setenv ("ethaddr", buf); + } + } +} /* w7o_env_init() */ + + +int misc_init_r (void) +{ + VPD vpd; /* VPD information */ + +#if defined(CONFIG_W7OLMG) + unsigned long greg; /* GPIO Register */ + + greg = in32 (PPC405GP_GPIO0_OR); + + /* + * XXX - Unreset devices - this should be moved into VxWorks driver code + */ + greg |= 0x41800000L; /* SAM, PHY, Galileo */ + + out32 (PPC405GP_GPIO0_OR, greg); /* set output pins to default */ +#endif /* CONFIG_W7OLMG */ + + /* + * Initialize W7O environment variables + */ + w7o_env_init (&vpd); + + /* + * Initialize the FPGA(s). + */ + if (init_fpga () == 0) + test_fpga ((unsigned short *) CONFIG_FPGAS_BASE); + + /* More POST testing. */ + post2 (); + + /* Done with hardware initialization and POST. */ + log_stat (ERR_POSTOK); + + /* Call silly, fail safe boot init routine */ + init_fsboot (); + + return (0); +} diff --git a/qemu/roms/u-boot/board/w7o/w7o.h b/qemu/roms/u-boot/board/w7o/w7o.h new file mode 100644 index 000000000..9ef682c66 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/w7o.h @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _W7O_H_ +#define _W7O_H_ +#include <config.h> + +/* AMCC 405GP PowerPC GPIO registers */ +#define PPC405GP_GPIO0_OR 0xef600700L /* GPIO Output */ +#define PPC405GP_GPIO0_TCR 0xef600704L /* GPIO Three-State Control */ +#define PPC405GP_GPIO0_ODR 0xef600718L /* GPIO Open Drain */ +#define PPC405GP_GPIO0_IR 0xef60071cL /* GPIO Input */ + +/* LMG FPGA <=> CPU GPIO signals */ +#define LMG_XCV_INIT 0x10000000L +#define LMG_XCV_PROG 0x04000000L +#define LMG_XCV_DONE 0x00400000L +#define LMG_XCV_CNFG_0 0x08000000L +#define LMG_XCV_IRQ_0 0x0L + +/* LMC FPGA <=> CPU GPIO signals */ +#define LMC_XCV_INIT 0x00800000L +#define LMC_XCV_PROG 0x40000000L +#define LMC_XCV_DONE 0x01000000L +#define LMC_XCV_CNFG_0 0x00004000L /* Shared with IRQ 0 */ +#define LMC_XCV_CNFG_1 0x00002000L /* Shared with IRQ 1 */ +#define LMC_XCV_CNFG_2 0x00001000L /* Shared with IRQ 2 */ +#define LMC_XCV_IRQ_0 0x00080000L /* Shared with GPIO 17 */ +#define LMC_XCV_IRQ_1 0x00040000L /* Shared with GPIO 18 */ +#define LMC_XCV_IRQ_3 0x00020000L /* Shared tiwht GPIO 19 */ + + +/* + * Setup FPGA <=> GPIO mappings + */ +#if defined(CONFIG_W7OLMG) +# define GPIO_XCV_INIT LMG_XCV_INIT +# define GPIO_XCV_PROG LMG_XCV_PROG +# define GPIO_XCV_DONE LMG_XCV_DONE +# define GPIO_XCV_CNFG LMG_XCV_CNFG_0 +# define GPIO_XCV_IRQ LMG_XCV_IRQ_0 +# define GPIO_GPIO_1 0x40000000L +# define GPIO_GPIO_6 0x02000000L +# define GPIO_GPIO_7 0x01000000L +# define GPIO_GPIO_8 0x00800000L +#elif defined(CONFIG_W7OLMC) +# define GPIO_XCV_INIT LMC_XCV_INIT +# define GPIO_XCV_PROG LMC_XCV_PROG +# define GPIO_XCV_DONE LMC_XCV_DONE +# define GPIO_XCV_CNFG LMC_XCV_CNFG_0 +# define GPIO_XCV_IRQ LMC_XCV_IRQ_0 +#else +# error "Unknown W7O board configuration" +#endif + +/* Power On Self Tests */ +extern void post2(void); +extern int test_led(void); +extern int test_sdram(unsigned long size); +extern void test_fpga(unsigned short *daddr); + +/* FGPA */ +extern int init_fpga(void); + +/* Misc */ +extern int temp_uart_init(void); +extern void init_fsboot(void); + +#endif /* _W7O_H_ */ diff --git a/qemu/roms/u-boot/board/w7o/watchdog.c b/qemu/roms/u-boot/board/w7o/watchdog.c new file mode 100644 index 000000000..ff1b21209 --- /dev/null +++ b/qemu/roms/u-boot/board/w7o/watchdog.c @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * W7O board level hardware watchdog. + */ +#include <common.h> +#include <config.h> + +#ifdef CONFIG_HW_WATCHDOG +#include <watchdog.h> + +void hw_watchdog_reset(void) +{ + volatile ushort *hwd = (ushort *)(CONFIG_SYS_W7O_EBC_PB7CR & 0xfff00000); + + /* + * Read the LMG's hwd register and toggle the + * watchdog bit to reset it. On the LMC, just + * reading it is enough, but toggling the bit + * doen't hurt either. + */ + *hwd = *hwd ^ 0x8000; + +} /* hw_watchdog_reset() */ + +#endif /* CONFIG_HW_WATCHDOG */ |