📄 tpe4.c
字号:
/* $Id: tpe4.c,v 1.6 2000/11/15 17:44:54 apc Exp $ *//* Copyright 2000 AG Electronics Ltd. *//* This code is distributed without warranty under the GPL v2 (see COPYING) */#include <bsp.h>#include <malloc.h>#include <ppc.h>#include <stdio.h>#include <console.h>#include <flash.h>#include <pci.h>#include <net.h>#include <stdarg.h>#include <io.h>#include <run.h>#include "asmstart.h"volatile unsigned char *tpe4reg;unsigned long memory_base;unsigned long bios_base;unsigned long bios_top;unsigned long memory_top;unsigned long physical_memory_size;#if 1static void pci_configure (void){ /* On bus 0, we don't configure device 0. Because it is us. */ int dev; pci_root.have_io_space = 1; pci_root.have_prefetch_space = 0; pci_root.fast_back_to_back = 1; printf("PCI configuration\n"); for (dev = 1; dev < 32; dev++) { u32 data; int result = pci_config_read_32 (0, dev, 0, 0, &data); if (result == 0 && data != 0xffffffff) pci_configure_device (&pci_root, dev, 0); } pci_assign_space (&pci_root, PCI_REGION_IO, 0x10000, 0x1000); pci_assign_space (&pci_root, PCI_REGION_MMIO, 0xfc000000, 0x80000000); pci_set_command(&pci_root);}#endifint memory_has_failed;#ifdef BSP_USE_FAKERAMstatic void write_64(unsigned data0, unsigned data1){ printf("0x%04x 0x%04x 0x%04x 0x%04x", data0 >> 16, data0 & 0xffff, data1 >> 16, data1 & 0xffff);}/* TPE4 memory banks start at 0x00000000, 0x00200000, 0x00400000, 0x00600000 */static void banktest(unsigned bank){ volatile unsigned *test = (void *)(bank << 21); unsigned data0 = 0; unsigned data1 = 0; unsigned failed0 = 0; unsigned failed1 = 0; unsigned td = 1; ppc_set_io_dbat(1, bank << 21 , 0x20000); test[0] = 0; test[1] = 0; data0 = test[0]; data1 = test[1]; if (data0 != 0 || data1 != 0) { printf("Error in bank %d: wrote zeros, got ", bank); write_64(data0, data1); printf("\n"); memory_has_failed = 1; failed0 |= data0; failed1 |= data1; } test[0] = 0xffffffff; test[1] = 0xffffffff; data0 = test[0]; data1 = test[1]; if (data0 != 0xffffffff || data1 != 0xffffffff) { printf("Error in bank %d: wrote ones, got ", bank); write_64(data0, data1); printf("\n"); memory_has_failed = 1; failed0 |= ~data0; failed1 |= ~data1; } while(td) { test[0] = 0; test[1] = td; data0 = test[0]; data1 = test[1]; if (data0 != 0 || data1 != td) { printf("Error in bank %d: wrote ", bank); write_64(0, td); printf(", got "); write_64(data0, data1); printf("\n"); memory_has_failed = 1; failed0 |= data0; failed1 |= data1 ^ td; } td <<= 1; } td = 1; while(td) { test[1] = 0; test[0] = td; data1 = test[1]; data0 = test[0]; if (data0 != td || data1 != 0) { printf("Error in bank %d: wrote ", bank); write_64(td, 0); printf(", got "); write_64(data0, data1); printf("\n"); memory_has_failed = 1; failed0 |= data0 ^ td; failed1 |= data1; } td <<= 1; } if (failed0 || failed1) { printf("Bank %d failure mask: ", bank); write_64(failed0, failed1); printf("\n"); } }#endifvoid bsp_init_pre_reloc(unsigned offset){ extern char __start[]; extern char __start_data[]; extern char __stack_end[]; extern char __heap_end[]; unsigned rom_image = (unsigned) __start & 0xfff00000; if (__heap_end > __stack_end) { malloc_add_pool(__stack_end, __heap_end - __stack_end); bios_top = (unsigned long) __heap_end; } else { malloc_add_pool(__heap_end, 256 * 1024); bios_top = 256*1024 + (unsigned long) __heap_end; } TftpLoadAddress = (unsigned char *)(__heap_end + 1024*1024); tpe4reg = (void *)0xff000000; *(volatile char *)0xff100014 = 0x8; ppc_setup_cpu(1); /* icache enable = 1 */ ppc_set_ibats_reloc(rom_image, 0xfff00000, 0x00100000); if ((rom_image & 0xf0000000) != 0xf0000000) ppc_set_io_dbat_reloc(2, rom_image, rom_image + offset, 0x00100000); ppc_enable_mmu(); init_console_16550(0xff100010, 6144000, 1); printf("Testing memory...\n"); banktest(0); banktest(1); banktest(2); banktest(3); if (memory_has_failed) { printf(" ****************************************************\n"); printf(" *** WARNING - A memory failure has been detected ***\n"); printf(" ****************************************************\n"); } memory_base = 0; memory_top = 128*1024 * 1024; physical_memory_size = memory_top; bios_base = (unsigned long) __start_data; /* If we have some working RAM, we copy the code and rodata into it. This allows us to reprogram the flash later. */ if (!memory_has_failed) { ppc_set_mem_dbat_reloc(2, rom_image, memory_top - 0x00100000, 0x00100000); memcpy(rom_image, rom_image + offset, 0x00100000); ppc_set_ibats_reloc(rom_image, memory_top - 0x00100000, 0x00100000); make_coherent(rom_image, 0x00100000); memory_top -= 0x00100000; } ppc_set_memory_dbat(physical_memory_size); ppc_set_io_dbat(3, 0xf0000000, 0x10000000); ppc_set_io_dbat(1, 0xe0000000, 0x10000000); ppc_enable_dcache();}void bsp_init_post_reloc(void){}extern int program_fpga(void);int running_from_pci_rom(void){ return !(tpe4reg[1] & 1);}static ioaddr mailbox;void bsp_init_post_hello(void){ struct pci_device *dev; extern char __stack_end[]; extern char __heap_end[]; if ((! memory_has_failed) || !(tpe4reg[1] & 1)) { init_flash_atmel040("BOOT", 0xff700000, 1); } program_fpga(); pci_configure(); if (__heap_end > __stack_end && ! memory_has_failed) { malloc_add_pool(__heap_end, 256*1024); bios_top = 256*1024 + (unsigned long) __heap_end; } printf("Memory from 0x%08lx to 0x%08lx, BIOS uses 0x%08lx to 0x%08lx\n", memory_base, memory_top, bios_base, bios_top);#ifdef FIXUP_TPV4 printf("TPV4 Fixups:"); dev = pci_find_device (0x109e, 0x036e, 0); if (dev) { u32 data; printf(" %02x:%02x(%x)", dev->bus->bus, dev->device, dev->function); pci_config_write_8(dev->bus->bus, dev->device, dev->function, 0x40, 1); pci_config_write_32(dev->bus->bus, dev->device, dev->function, 0x2c, 0x010115cb); pci_config_read_32(dev->bus->bus, dev->device, dev->function, 0x2c, &data); pci_config_write_8(dev->bus->bus, dev->device, dev->function, 0x40, 0); } printf("\n"); #endif /* Find the 21554 scratchpad */ dev = pci_find_device(0x1011, 0x46, 0); if (dev) mailbox = dev->region[0] + 0xa8; printf("mailbox at 0x%x\n", mailbox);}void bsp_indicate_dead(void){ for(;;) { volatile int i; *(volatile char *)0x61000004 = 0x8; for(i = 0; i < 1000000; i++) ; *(volatile char *)0x61000004 = 0x4; for(i = 0; i < 1000000; i++) ; } }extern void ata_test(void);void bsp_identify(void){ printf("TPE4 BSP: booted "); if (memory_has_failed) printf("and running "); if (tpe4reg[1] & 1) printf("from ROM"); else printf("from PCI"); if (! memory_has_failed) printf(", running relocated in RAM"); printf(", bus clock %dMHz\n", (tpe4reg[1] & 8) ? 66 : 100); /* ata_test(); */ ppc_identify();}#ifdef HAVE_netint NetInit(void){ extern NetCard_t NetNE2100; NetCard_t * nc = &NetNE2100; if (NetCard != nc) { if (NetCard) (*NetCard->halt)(); if (!(*nc->init)()) return 0; NetCard = nc; } return 1;}#endifunsigned bsp_clock_speed(void){ if (tpe4reg[1] & 8) return 66666000 / 4; else return 100000000 / 4;}/* Start a loaded executable */void bsp_run_executable(unsigned entry, char *cmd_line, unsigned initrd_start, unsigned initrd_length){ unsigned bootblock[5]; printf("Bsp_run\n"); bootblock[0] = physical_memory_size; bootblock[1] = (unsigned) cmd_line; if (cmd_line) bootblock[2] = (unsigned) (cmd_line + strlen(cmd_line)); else bootblock[2] = 0; bootblock[3] = initrd_start; bootblock[4] = initrd_start + initrd_length; make_coherent(bootblock, 128); printf("Bootblock at 0x%p\n", bootblock); ppc_run_executable(entry, 0x54504534, bootblock); /* TPE4 */}void bsp_mailbox_check(void){ u32 new_scratchpad; u32 data; if (mailbox) { new_scratchpad = read_32(mailbox); if (new_scratchpad & 0x80000000) switch(new_scratchpad & 0x7fffffff) { case 1: printf("Sending tftpload base 0x%08x\n", (u32) TftpLoadAddress); *(volatile unsigned *) TftpLoadAddress = 0xdeadfeed; write_32(mailbox, (u32) TftpLoadAddress); break; case 2: printf("Load ELF file\n"); code_loaded = 1; do_unpack(0, NULL); printf("Arguments %s\n", (void *) read_32(mailbox + 4)); if (executable_start_address != 0xffffffff) bsp_run_executable(executable_start_address, (void *) read_32(mailbox + 4), read_32(mailbox + 8), read_32(mailbox + 12)); else printf("Not valid executable\n"); break; default: break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -