📄 tgt_machdep.c
字号:
/* $Id: tgt_machdep.c,v 1.11 2002/11/16 18:01:31 pefo Exp $ *//* * Copyright (c) 2000-2001 Opsycon AB (www.opsycon.se) * Copyright (c) 2000-2001 Rtmx, Inc (www.rtmx.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for Rtmx, Inc by * Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <sys/types.h>#include <stdio.h>#include <termio.h>#include <string.h>#include <time.h>#include <sys/device.h>#include <dev/pci/pcivar.h>#include <dev/ic/ds15x1reg.h>#include <machine/cpu.h>#include <machine/pio.h>#include <machine/inline_asm.h>#include <autoconf.h>#include <pflash.h>#include <pmon/dev/gt64260reg.h>#include "target/ev64260.h"#include "dev/pflash_tgt.h"#include <stdlib.h>#include <pmon.h>#include <pmon/netio/netio.h>#include <pmon/dev/ns16550.h>#include "flash.h"#if (NMOD_FLASH_AMD + NMOD_FLASH_INTEL) == 0#ifdef HAVE_FLASH#undef HAVE_FLASH#endif#ifdef NVRAM_IN_FLASH#error "NVRAM_IN_FLASH defined but have no flash support!"#endif#else#define HAVE_FLASH#endif#include "pcibr.h"#include "mainbus.h"#include "mod_tod.h"extern int gt_uart __P((int, char *, unsigned long, int));extern unsigned char hwethadr[6];static int md_pipefreq = 0; /* Zero means have to probe! */static int md_cpufreq = 0; /* Zero means have to probe! */static int clk_invalid = 0;static int nvram_invalid = 0;ConfigEntry ConfigTable[] ={#if defined(GT_UART) { (char *) GT_COM1, 0, gt_uart, 256, B9600 }, { (char *) GT_COM2, 0, gt_uart, 256, B9600 },#else { (char *)COM1_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ }, { (char *)COM2_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },#endif { 0 }};static void _probe_frequencies __P((void));static int cksum __P((void *, size_t, int));#ifndef NVRAM_IN_FLASHvoid nvram_get __P((char *));void nvram_put __P((char *));#endif/* * Target dependent version printout. * Printout available target version information. */voidtgt_cmd_vers(){}/* * This function makes inital HW setup for debugger and * returns the apropriate setting for the status register. */register_ttgt_enable(int machtype){ /* XXX Do any HW specific setup */ return(PSL_IR|PSL_DR|PSL_FP|PSL_RI|PSL_ME|PSL_FE_DFLT);}#ifdef HAVE_LOGO/* * Print out any target specific logo */voidtgt_logo(){ printf("\n"); printf("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n"); printf("[[[ [[[[ [[[[[[[[[[ [[[[ [[[[ [[[[[[[ [[\n"); printf("[[ [[[[[[[[ [[[ [[[[[[[[ [[[ [[[[[[[[ [[[ [[[[[[ [[\n"); printf("[[ [[[[[[[[[[ [[[ [ [[[[[[ [ [[[ [[[[[[[[[[ [[[ [ [[[[[ [[\n"); printf("[[ [[[[[[[[[[ [[[ [[ [[[[ [[ [[[ [[[[[[[[[[ [[[ [[ [[[[ [[\n"); printf("[[ [[[[[[[[ [[[ [[[ [[ [[[ [[[ [[[[[[[[[[ [[[ [[[ [[[ [[\n"); printf("[[ [[[[ [[[[ [[[[ [[[ [[[[[[[[[[ [[[ [[[[ [[ [[\n"); printf("[[ [[[[[[[[[[[[[[[ [[[[[ [[[[[ [[[ [[[[[[[[[[ [[[ [[[[[ [ [[\n"); printf("[[ [[[[[[[[[[[[[[[ [[[[[[[[[[[[ [[[ [[[[[[[[[[ [[[ [[[[[[ [[\n"); printf("[[ [[[[[[[[[[[[[[[ [[[[[[[[[[[[ [[[ [[[[[[[[ [[[ [[[[[[[ [[\n"); printf("[[ [[[[[[[[[[[[[[[ [[[[[[[[[[[[ [[[[ [[[[ [[[[[[[[ [[\n"); printf("[[[[[[[2000][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n");}#endif /* HAVE_LOGO *//* * Print out any target specific memory information */voidtgt_memprint(){}/* * Print out BSP specific info and the CPU type. */voidtgt_machprint(){ printf("Copyright (c) 2001-2002, Opsycon AB.\n"); printf("CPU PowerPC %s @", md_cpuname());} /* * Return a suitable address for the client stack. * Usually top of RAM memory. */register_ttgt_clienttos(){ return((memorysize & ~7) - 64);}/*************************************************************************//* * Target dependent clock and TOD chip support code * ================================================ */static void_probe_frequencies(){ int i;#ifdef HAVE_TOD int timeout, cur, sec, cnt;#endif SBD_DISPLAY ("FREQ", CHKPNT_FREQ); md_pipefreq = 400000000; /* Defaults, must be set now! */ md_cpufreq = 100000000; clk_invalid = 0;#ifdef HAVE_TOD /* * Make sure clock is updating. */ i = inb(RTC_BASE + DS_REG_CTLB); outb(RTC_BASE + DS_REG_CTLB, i | DS_CTLB_TE); /* * Do the next twice for two reasons. First make sure we run from * cache. Second make sure synched on second update. (Pun intended!) */ for(i = 2; i != 0; i--) { cnt = get_count(); timeout = 10000000; sec = inb(RTC_BASE + DS_REG_SEC); do { timeout--; cur = inb(RTC_BASE + DS_REG_SEC); } while(timeout != 0 && cur == sec); cnt = get_count() - cnt; if(timeout == 0) { clk_invalid = 1; } } /* * Calculate the external bus clock frequency. */ md_cpufreq = (cnt + 50000) / 100000; md_cpufreq *= 400000;#endif /* HAVE_TOD */ md_pipefreq = md_getpipefreq(md_cpufreq);}/* * Returns the CPU pipeline clock frequency */inttgt_pipefreq(){ if(md_pipefreq == 0) { _probe_frequencies(); } return(md_pipefreq);}/* * Returns the external clock frequency, usually the bus clock */inttgt_cpufreq(){ if(md_cpufreq == 0) { _probe_frequencies(); } return(md_cpufreq);}voidtgt_rtinit(){}#if NCMD_DATE/* * Returns the current time if a TOD clock is present or 0 * This code is defunct after 2088... (out of bits) */#define YEARDAYS(year) ((((year) % 4) == 0 && \ ((year % 100) != 0 || (year % 400) == 0)) ? 366 : 365)#define SECMIN (60) /* seconds per minute */#define SECHOUR (60*SECMIN) /* seconds per hour */#define SECDAY (24*SECHOUR) /* seconds per day */#define SECYR (365*SECDAY) /* seconds per common year */static const short dayyr[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };static intFROMBCD(int x){ return((x >> 4) * 10 + (x & 0xf));}static intTOBCD(int x){ return((x / 10 * 16) + (x % 10));}time_ttgt_gettime(){ struct tm tm; int ctrlbsave; time_t t; if(!clk_invalid) { /* Freeze readout data regs */ ctrlbsave = inb(RTC_BASE + DS_REG_CTLB); outb(RTC_BASE + DS_REG_CTLB, ctrlbsave & ~DS_CTLB_TE); tm.tm_sec = FROMBCD(inb(RTC_BASE + DS_REG_SEC)); tm.tm_min = FROMBCD(inb(RTC_BASE + DS_REG_MIN)); tm.tm_hour = FROMBCD(inb(RTC_BASE + DS_REG_HOUR)); tm.tm_wday = FROMBCD(inb(RTC_BASE + DS_REG_WDAY)); tm.tm_mday = FROMBCD(inb(RTC_BASE + DS_REG_DATE)); tm.tm_mon = FROMBCD(inb(RTC_BASE + DS_REG_MONTH) & 0x1f) - 1; tm.tm_year = FROMBCD(inb(RTC_BASE + DS_REG_YEAR)); tm.tm_year += 100 * (FROMBCD(inb(RTC_BASE + DS_REG_CENT)) - 19); outb(RTC_BASE + DS_REG_CTLB, ctrlbsave | DS_CTLB_TE); tm.tm_isdst = tm.tm_gmtoff = 0; t = gmmktime(&tm); } else { t = 957960000; /* Wed May 10 14:00:00 2000 :-) */ } return(t);}/* * Set the current time if a TOD clock is present */voidtgt_settime(time_t t){ struct tm *tm; int ctrlbsave; if(!clk_invalid) { tm = gmtime(&t); /* Enable register writing */ ctrlbsave = inb(RTC_BASE + DS_REG_CTLB); outb(RTC_BASE + DS_REG_CTLB, ctrlbsave & ~DS_CTLB_TE); outb(RTC_BASE + DS_REG_CENT, TOBCD(tm->tm_year / 100 + 19)); outb(RTC_BASE + DS_REG_YEAR, TOBCD(tm->tm_year % 100)); outb(RTC_BASE + DS_REG_MONTH,TOBCD(tm->tm_mon + 1)); outb(RTC_BASE + DS_REG_DATE, TOBCD(tm->tm_mday)); outb(RTC_BASE + DS_REG_WDAY, TOBCD(tm->tm_wday)); outb(RTC_BASE + DS_REG_HOUR, TOBCD(tm->tm_hour)); outb(RTC_BASE + DS_REG_MIN, TOBCD(tm->tm_min)); outb(RTC_BASE + DS_REG_SEC, TOBCD(tm->tm_sec)); /* Transfer new time to counters */ outb(RTC_BASE + DS_REG_CTLB, ctrlbsave | DS_CTLB_TE); }}#elsetime_ttgt_gettime(){ return(957960000); /* Wed May 10 14:00:00 2000 :-) */}#endif /* NCMD_DATE */#ifdef HAVE_FLASH/*************************************************************************//* * Target dependent Flash programming support code * =============================================== *//* * Table of flash devices on target. See pflash_tgt.h. * tgt_flashmap returns the address of the table describing the * current flash mapping. Some systems have only one while others * have severals depending on boot flash rom mapping etc. */struct fl_map tgt_fl_map8[] = { TARGET_FLASH_DEVICES_8 };struct fl_map tgt_fl_map32[] = { TARGET_FLASH_DEVICES_32};voidtgt_flashinit(){}struct fl_map *tgt_flashmap(){ int bootpar; bootpar = GT_READ(GT_BOOT_PAR); if((bootpar & 0x00300000) == 0) { return(tgt_fl_map8); } else { return(tgt_fl_map32); }}/* * Do whatever HW action requiered to disable flash writing. * If not supported by the target, just do nothing. */voidtgt_flashwrite_disable(){}/* * Do whatever HW action requiered to enable flash writing. * If flash writing can't be enabled by SW return(0). */inttgt_flashwrite_enable(){ return(1);}/* * Some flash memory designs have a page select feature. * Return zero if page ok, otherwise -1. */inttgt_flashsetpageno(int page){ return(0);}voidtgt_flashinfo(void *p, size_t *t){ struct fl_map *map; map = fl_find_map(p); if(map) { *t = map->fl_map_size; } else { *t = 0; }}/* * This function is called from the boot commands when the -f switch * is given. */voidtgt_flashprogram(void *p, int size, void *s, int endian){ printf("Programming flash %p:%p into %p\n", s, size, p); if(fl_erase_device(p, size, TRUE)) { printf("Erase failed!\n"); return; } if(fl_program_device(p, s, size, TRUE)) { printf("Programming failed!\n"); } fl_verify_device(p, s, size, TRUE);}#endif/*************************************************************************//* * Target dependent Networking support code * ========================================= * * Don't add code to work the HW here which is not called from the MI code. */voidtgt_netinit(){}/* * Ethernet adapters without a serial rom or other means for getting * it's ethernet address can pick it up here. */inttgt_ethaddr(char *p){ bcopy((void *)&hwethadr, p, 6); return(0);}voidtgt_netreset(){}/* * Create stubs if network is not compiled in */#ifdef INETvoidtgt_netpoll(){ splx(splhigh());}#elseextern void longjmp(label_t *, int);void gsignal(label_t *jb, int sig); voidgsignal(label_t *jb, int sig){ if(jb != NULL) { longjmp(jb, 1); }}int netopen(const char *a, int b){ return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -