From: wdenk Date: Wed, 11 Oct 2000 22:04:27 +0000 (+0000) Subject: * Added MPC855 support X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=149d456714db67e86e468695f94a6a9a39ae992b;p=users%2Frw%2Fppcboot.git * Added MPC855 support * Tested with MPC8xx at 80 MHz CPU clock / 40 MHz bus clock * Don't block booting of other OS than Linux using "bootm" * Added Cogent port (by Murray Jensen ) * Added KGDB support (by Murray Jensen) Warning: the KGDB code is *big*. If you include it you'll probably need to throw out lots of other features or increas the size of your firmware memory. * Extended flash addressing to use sector numbers --- diff --git a/CHANGELOG b/CHANGELOG index 7772dd4..e719afa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -51,11 +51,6 @@ Open Issues: structure containing `monitor functions'; add things like malloc() and free(). -* ALL: - - Put `implementation' features in #ifdef's to make it possible to - shrink monitor size to specific needs - * BUG: Fix Exception handling for "Software Emulation Exception" etc. diff --git a/Makefile b/Makefile index e6952f4..93d9378 100644 --- a/Makefile +++ b/Makefile @@ -101,6 +101,7 @@ unconfig: TQM823L_config \ TQM850L_config \ +TQM855L_config \ TQM860L_config : unconfig @echo "Configuring for $(@:_config=) Board..." ; \ cd include ; \ @@ -150,6 +151,14 @@ ADCIOP_config: unconfig echo "CPU = ppc4xx" >>config.mk ; \ echo "#include " >config.h +cogent_mpc8xx_config: unconfig + @echo "Configuring for $(@:_config=) Board..." ; \ + cd include ; \ + echo "ARCH = ppc" > config.mk ; \ + echo "BOARD = cogent" >>config.mk ; \ + echo "CPU = mpc8xx" >>config.mk ; \ + echo "#include " >config.h + ######################################################################### clean: diff --git a/README b/README index 4b92fdb..c4522fd 100644 --- a/README +++ b/README @@ -148,11 +148,13 @@ The following options need to be configured: - Console Interface: Define exactly one of - CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2 + CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2 or + CONFIG_8xx_CONS_NONE - Console Baudrate: CONFIG_BAUDRATE - in bps Select one of 9600, 19200, 38400, 57600, 115200 + (or 230400 if CONFIG_COGENT is defined) - Boot Delay: CONFIG_BOOTDELAY - in seconds Delay before automatically booting the default image; @@ -180,6 +182,11 @@ The following options need to be configured: allows to download binary files over the serial line using Kermit protocol. +- Kgdb Serial Baudrate: (if CFG_CMD_KGDB is defined) + CONFIG_KGDB_BAUDRATE + Select one of 9600, 19200, 38400, 57600, 115200 + (or 230400 if CONFIG_COGENT is defined) + - Monitor Functions: CONFIG_COMMANDS Most monitor functions can be selected (or @@ -196,16 +203,24 @@ The following options need to be configured: CFG_CMD_IMI iminfo CFG_CMD_CACHE icache, dcache CFG_CMD_FLASH flinfo, erase, protect - CFG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base, loop, mtest + CFG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base, + loop, mtest CFG_CMD_NET bootp, tftpboot, rarpboot CFG_CMD_ENV saveenv + CFG_CMD_KGDB kgdb ------------------------- CFG_CMD_ALL all - If you don't define CONFIG_COMMANDS it defaults to CFG_CMD_ALL . + CFG_CMD_DFL Default configuration; at the moment + this is defined as + (CFG_CMD_ALL & ~(CFG_CMD_KGDB)) + = everything except KGDB - EXAMPLE: If you want all functions except of network support you - can write: + If you don't define CONFIG_COMMANDS it defaults to +CFG_CMD_DFL . + + EXAMPLE: If you want all functions except of network + support you can write: #define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET) @@ -243,6 +258,10 @@ Configuration Settings: - CFG_SDRAM_BASE: Physical start address of SDRAM. _Must_ be 0 here. +- CFG_MBIO_BASE: + Physical start address of Motherboard I/O (if using a + Cogent motherboard) + - CFG_FLASH_BASE: Physical start address of Flash memory. @@ -360,6 +379,7 @@ configurations; the following names are suported: ADCIOP_config FADS850SAR_config SPD823TS_config + cogent_mpc8xx_config If the system board that you have is not listed, then you will need diff --git a/cogent/Makefile b/cogent/Makefile new file mode 100644 index 0000000..43b68cd --- /dev/null +++ b/cogent/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS := $(foreach M,$(CMA_MB) $(CMA_IOMS),$(foreach O,$($M_O),$M/$O)) + +$(LIB): $(OBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/cogent/README b/cogent/README new file mode 100644 index 0000000..202dd02 --- /dev/null +++ b/cogent/README @@ -0,0 +1,115 @@ +Cogent Modular Architecture configuration +----------------------------------------- + +As the name suggests, the Cogent platform is a modular system where you have a +motherboard into which plugs a cpu module and one or more i/o modules. This +provides very nice flexibility, but makes the configuration task somewhat +harder. + +The possible Cogent motherboards are: + +Code Config Variable Description +---- --------------- ----------- + +CMA101 CONFIG_CMA101 32MB ram, 2 ser, 1 par, rtc, dipsw, + 2x16 lcd, eth(?) +CMA102 CONFIG_CMA102 32MB ram, 2 ser, 1 par, rtc, dipsw, + 2x16 lcd +CMA111 CONFIG_CMA111 32MB ram, 1MB flash, 4 ser, 1 par, + rtc, ps/2 kbd/mse, 2x16 lcd, 2xPCI, + 10/100TP eth +CMA120 CONFIG_CMA120 32MB ram, 1MB flash, 4 ser, 1 par, + rtc, ps/2 kbd/mse, 2x16 lcd, 2xPCI, + 10/100TP eth, 2xPCMCIA, video/lcd-panel +CMA150 CONFIG_CMA150 8MB ram, 1MB flash, 2 ser, 1 par, rtc, + ps/2 kbd/mse, 2x16 lcd + +The possible Cogent PowerPC CPU modules are: + +Code Config Variable Description +---- --------------- ----------- + +CMA278-603EV CONFIG_CMA278_603EV PPC603ev CPU, 66MHz clock, 512K EPROM, + JTAG/COP +CMA278-603ER CONFIG_CMA278_603ER PPC603er CPU, 66MHz clock, 512K EPROM, + JTAG/COP +CMA278-740 CONFIG_CMA278_740 PPC740 CPU, 66MHz clock, 512K EPROM, + JTAG/COP +CMA280-509 CONFIG_CMA280_509 MPC505/509 CPU, 50MHz clock, + 512K EPROM, BDM +CMA282 CONFIG_CMA282 MPC8260 CPU, 66MHz clock, 512K EPROM, + JTAG, 16M RAM, 1 x ser (SMC2), + 1 x 10baseT PHY (SCC4), 1 x 10/100 TP + PHY (FCC1), 2 x 48pin DIN (FCC2 + TDM1) +CMA285 CONFIG_CMA285 MPC801 CPU, 33MHz clock, 512K EPROM, + BDM +CMA286-21 CONFIG_CMA286_21 MPC821 CPU, 66MHz clock, 512K EPROM, + BDM, 16M RAM, 2 x ser (SMC1 + SMC2), + 1 x 10baseT PHY (SCC2) +CMA286-60-OLD CONFIG_CMA286_60_OLD MPC860 CPU, 33MHz clock, 128K EPROM, + BDM +CMA286-60 CONFIG_CMA286_60 MPC860 CPU, 66MHz clock, 512K EPROM, + BDM, 16M RAM, 2 x ser (SMC1 + SMC2), + 1 x 10baseT PHY (SCC2) +CMA286-60P CONFIG_CMA286_60P MPC860P CPU, 66MHz clock, 512K EPROM, + BDM, 16M RAM, 2 x ser (SMC1 + SMC2), + 1 x 10baseT PHY (SCC2) +CMA287-23 CONFIG_CMA287_23 MPC823 CPU, 33MHz clock, 512K EPROM, + BDM +CMA287-50 CONFIG_CMA287_50 MPC850 CPU, 33MHz clock, 512K EPROM, + BDM + +(there are a lot of other cpu modules with ARM, MIPS and M-CORE CPUs, +but we'll worry about those later). + +The possible Cogent CMA I/O Modules are: + +Code Config Variable Description +---- --------------- ----------- + +CMA302 CONFIG_CMA302 up to 16M flash, ps/2 keyboard/mouse +CMA352 CONFIG_CMA352 CMAbus <=> PCI + +Currently supported: + + Motherboards: CMA102 + CPU Modules: CMA286-60-OLD + I/O Modules: CMA302 I/O module + +To configure, perform the usual ppcboot configuration task of editing +"include/config_cogent_mpc8xx.h" and reviewing all the options and settings in +there. In particular, check the chip select values installed into the memory +controller's various option and base registers - these are set by the defines +CFG_CMA_CSn_{BASE,SIZE} and CFG_{B,O}Rn_PRELIM. Also be careful of the clock +settings installed into the SCCR - via the define CFG_SCCR. Finally, decide +whether you want the serial console on motherboard serial port A or on one of +the 8xx SMC ports, and set CONFIG_8xx_CONS_{SMC1,SMC2,NONE} accordingly (NONE +means use Cogent motherboard serial port A). + +Then edit the file "cogent/config.mk". Firstly, set TEXT_BASE to be the base +address of the EPROM for the CPU module. This should be the same as the value +selected for CFG_MONITOR_BASE in "include/config_cogent_*.h" (in fact, I have +made this automatic via the -DTEXT_BASE=... option in CPPFLAGS). + +Finally, set the values of the make variables $(CMA_MB) and $(CMA_IOMS). + +$(CMA_MB) is the name of the directory that contains support for your +motherboard. At this stage, only "cma10x" exists, which supports the CMA101 +and CMA102 motherboards - but only selected devices, namely serial, lcd and +dipsw. + +$(CMA_IOMS) is a list of zero or more directories that contain support for the +i/o modules you have installed. At this stage, only "cma302" exists, which +supports the CMA302 flash i/o module - but only the flash part, not the ps/2 +keyboard and mouse interfaces. + +There should be a make variable for each of the above directories, which is +the directory name with "_O" appended. This make variable is a list of object +files to compile from that directory and include in the library. + + e.g. cma10x_O = serial.o ... + +That's it. Good Luck. + +Murray.Jensen@cmst.csiro.au +August 31, 2000. diff --git a/cogent/README.cma286 b/cogent/README.cma286 new file mode 100644 index 0000000..aeebc85 --- /dev/null +++ b/cogent/README.cma286 @@ -0,0 +1,69 @@ +CPU module revisions +-------------------- + +My cpu module has the model number "CMA286-60-990526-01". My motherboard +has the model number "CMA102-32M-990526-01". These are both fairly old, +and may not reflect current design. In particular, I can see from the +Cogent web site that the CMA286 has been significantly redesigned - it +now has on board RAM (4M), ethernet 10baseT PHY (on SCC2), 2 serial ports +(SMC1 and SMC2), and 48pin DIN for the FEC (if present i.e. MPC860T), and +also the EPROM is 512K. + +My CMA286-60 has none of this, and only 128K EPROM. In addition, the CPU +clock is listed as 66MHz, whereas mine is 33.333MHz. + +Clocks +------ + +Quote from my "CMA286 MPC860/821 User's Manual": + +"When setting up the Periodic Interrupt Timer (PIT), be aware that the +CMA286 places the MPC860/821 in PLL X1 Mode. This means that we feed +a 25MHz clock directly into the MPC860/821. This mode sets the divisor +for the PIT to be 512. In addition, the Time Base Register (TMB) +divisor is set to 16." + +I interpreted this information to mean that EXTCLK is 25MHz and that at +power on reset, MODCK1=1 and MODCK2=0, which selects EXTCLK as the +source for OSCCLK and PITRTCLK, sets RTDIV to 512 and sets MF (the +multiplication factor) to 1 (I assume this is what they mean by X1 +mode above). MF=1 means the cpus internal clock runs at the same +rate as EXTCLK i.e. 25MHz. + +Furthermore, since SCCR[TBS] (the Time Base Source selector bit in the +System Clock and Reset Control register) is set in the cpu initialisation +code, the TMBCLK source is forced to be GCLK2 and the TMBCLK prescale is +forced to be 16. This results in TMBCLK=1562500. + +One problem - since PITRTCLK source is EXTCLK (25Mhz) and RTDIV is 512, +PITRTCLK will be 48828.125 (huh?). Another quote from the MPC860 Users +Manual: + +"When used by the real-time clock (RTC), the PITRTCLK source is first +divided as determined by RTDIV, and then divided in the RTC circuits by +either 8192 or 9600. Therefore, in order for the RTC to count in +seconds, the clock source must satisfy: + + (EXTCLK or OSCM) / [(4 or 512) x (8192 or 9600)] = 1 + +The RTC will operate with other frequencies, but it will not count in +units of seconds." + +Therefore, the internal RTC of the MPC860 is not going to count in +seconds, so we must use the motherboard RTC (if we need a RTC). + +I presume this means that they do not provide a fixed oscillator for +OSCM. The code in get_gclk_freq() assumes PITRTCLK source is OSCM, +RTDIV is 4, and that OSCM/4 is 8192 (i.e. a ~32KHz oscillator). Since +the CMA286-60 doesn't have this (at least mine doesn't) we can't use +the code in get_gclk_freq(). + +Finally, it appears that the internal clock in my CMA286-60 is actually +33.333MHz. Which makes TMBCLK=2083312.5 (another huh?) and +PITRTCLK=65103.515625 (bloody hell!). + +If anyone finds anything wrong with the stuff above, I would appreciate +an email about it. + +Murray Jensen +21-Aug-00 diff --git a/cogent/cma10x/cma10x.c b/cogent/cma10x/cma10x.c new file mode 100644 index 0000000..18ab34f --- /dev/null +++ b/cogent/cma10x/cma10x.c @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include "dipsw.h" +#include "lcd.h" + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int +checkboard(void) +{ + printf ("Cogent " COGENT_MOTHERBOARD " motherboard with a " + COGENT_CPU_MODULE " CPU Module\n"); + return (0); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Miscelaneous platform dependent initialisations while still + * running in flash + */ + +int +misc_init_f(void) +{ + printf (" DIPSW: "); + dipsw_init(); + return (0); +} + +/* ------------------------------------------------------------------------- */ + +long int +initdram(int board_type) +{ + unsigned char dipsw_val; + int dual, size0, size1; + long int memsize; + + dipsw_val = dipsw_cooked(); + + dual = dipsw_val & 0x01; + size0 = (dipsw_val & 0x08) >> 3; + size1 = (dipsw_val & 0x04) >> 2; + + if (size0) + if (size1) + memsize = 16L * 1024L * 1024L; + else + memsize = 1L * 1024L * 1024L; + else + if (size1) + memsize = 4L * 1024L * 1024L; + else { + printf("[Illegal dip switch settings - assuming 16Mbyte SIMMs] "); + memsize = 16L * 1024L * 1024L; /* shouldn't happen - guess 16M */ + } + + if (dual) + memsize *= 2L; + + return (memsize); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Miscelaneous platform dependent initialisations after monitor + * has been relocated into ram + */ + +void +misc_init_r(bd_t *bd) +{ + printf (" LCD: "); + lcd_init(); + +#if 0 + printf (" RTC: "); + rtc_init(); + + printf (" PAR: "); + parallel_init(); +#endif +} diff --git a/cogent/cma10x/cma10x.h b/cogent/cma10x/cma10x.h new file mode 100644 index 0000000..cfee1a3 --- /dev/null +++ b/cogent/cma10x/cma10x.h @@ -0,0 +1,162 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CMA10x Motherboard I/O Address Maps + * + * The size of the motherboard i/o address space is 32 Mbytes. Its location + * in the physical address space of the cpu is given by CFG_MBIO_BASE. + * This value is determined by the cpu module plugged into the motherboard + * and is configured elsewhere. + * + * All motherboard I/O devices use byte lane 0 (D0-7) only, for their + * transfers, i.e. only 8 bit, or 1 byte, transfers can take place, so + * all the registers are only 8 bits wide. All I/O registers within the + * devices are 8 bytes apart. + * + * For big endian addressing, the register will be at byte 7 (the address + * + 7). For little endian addressing, the register will be at byte 0 (the + * address + 0). To learn the endianess we must include + */ + +/* Motherboard I/O Address Maps */ +#define CMA_MBIO_ROMLOW_BASE (CFG_MBIO_BASE+0x0000000) +#define CMA_MBIO_ROMLOW_SIZE 0x800000 +#define CMA_MBIO_RTC_BASE (CFG_MBIO_BASE+0x0800000) +#define CMA_MBIO_RTC_SIZE 0x4000 +#define CMA_MBIO_SERPAR_BASE (CFG_MBIO_BASE+0x0900000) +#define CMA_MBIO_SERIALB_BASE (CMA_MBIO_SERPAR_BASE+0x00) +#define CMA_MBIO_SERIALA_BASE (CMA_MBIO_SERPAR_BASE+0x40) +#define CMA_MBIO_PARALLEL_BASE (CMA_MBIO_SERPAR_BASE+0x80) +#define CMA_MBIO_SERPAR_SIZE 0x90 +#define CMA_MBIO_LCD_BASE (CFG_MBIO_BASE+0x0b00000) +#define CMA_MBIO_LCD_SIZE 0x10 +#define CMA_MBIO_DIPSW_BASE (CFG_MBIO_BASE+0x0c00000) +#define CMA_MBIO_DIPSW_SIZE 0x10 +#define CMA_MBIO_SLOT1CFG_BASE (CFG_MBIO_BASE+0x1100000) +#define CMA_MBIO_SLOT1CFG_SIZE 0x100000 +#define CMA_MBIO_SLOT2CFG_BASE (CFG_MBIO_BASE+0x1200000) +#define CMA_MBIO_SLOT2CFG_SIZE 0x100000 +#define CMA_MBIO_SLOT3CFG_BASE (CFG_MBIO_BASE+0x1300000) +#define CMA_MBIO_SLOT3CFG_SIZE 0x100000 +#define CMA_MBIO_ROMHIGH_BASE (CFG_MBIO_BASE+0x1800000) +#define CMA_MBIO_ROMHIGH_SIZE 0x800000 + +#include + +#ifndef __ASSEMBLY__ + +/* a single CMA10x motherboard i/o register */ +typedef + struct { +#if defined(__LITTLE_ENDIAN) + unsigned char value; +#endif + unsigned char filler[7]; +#if defined(__BIG_ENDIAN) + unsigned char value; +#endif + } +cma_mbio_reg; + +extern inline unsigned char +cma_mbio_reg_read(volatile cma_mbio_reg *reg) +{ + unsigned char data = reg->value; + asm volatile ("eieio" : : : "memory"); + return data; +} + +extern inline void +cma_mbio_reg_write(volatile cma_mbio_reg *reg, unsigned char data) +{ + reg->value = data; + asm volatile ("eieio" : : : "memory"); +} + +/* MK48T02 RTC registers */ +typedef + struct { + cma_mbio_reg sram[2040];/* Battery-Backed SRAM */ + cma_mbio_reg clk_ctl; /* Clock Control Register */ + cma_mbio_reg clk_sec; /* Clock Seconds Register */ + cma_mbio_reg clk_min; /* Clock Minutes Register */ + cma_mbio_reg clk_hour; /* Clock Hour Register */ + cma_mbio_reg clk_day; /* Clock Day Register */ + cma_mbio_reg clk_date; /* Clock Date Register */ + cma_mbio_reg clk_month; /* Clock Month Register */ + cma_mbio_reg clk_year; /* Clock Year Register */ + } +cma_mbio_rtc; + +/* ST16C522 Serial I/O */ +typedef + struct { + cma_mbio_reg ser_rhr; /* Receive Holding Register (R, DLAB=0) */ + cma_mbio_reg ser_ier; /* Interrupt Enable Register (R/W, DLAB=0) */ + cma_mbio_reg ser_isr; /* Interrupt Status Register (R) */ + cma_mbio_reg ser_lcr; /* Line Control Register (R/W) */ + cma_mbio_reg ser_mcr; /* Modem Control Register (R/W) */ + cma_mbio_reg ser_lsr; /* Line Status Register (R) */ + cma_mbio_reg ser_msr; /* Modem Status Register (R/W) */ + cma_mbio_reg ser_spr; /* Scratch Pad Register (R/W) */ + } +cma_mbio_serial; + +#define ser_thr ser_rhr /* Transmit Holding Register (W, DLAB=0) */ +#define ser_brl ser_rhr /* Baud Rate Divisor Low Byte (R/W, DLAB=1) */ +#define ser_brh ser_ier /* Baud Rate Divisor High Byte (R/W, DLAB=1) */ +#define ser_fcr ser_isr /* FIFO Control Register (W) */ +#define ser_nop ser_lsr /* No Operation (W) */ + +/* ST16C522 Parallel I/O */ +typedef + struct { + cma_mbio_reg par_rdr; /* Port Read Data Register (R) */ + cma_mbio_reg par_sr; /* Status Register (R) */ + cma_mbio_reg par_cmd; /* Command Register (R) */ + } +cma_mbio_parallel; + +#define par_wdr par_rdr /* Port Write Data Register (W) */ +#define par_ios par_sr /* I/O Select Register (W) */ +#define par_ctl par_cmd /* Control Register (W) */ + +/* HD44780 LCD Display */ +typedef + struct { + cma_mbio_reg lcd_ccr; /* Current Character Register (R/W) */ + cma_mbio_reg lcd_bsr; /* Busy Status Register (R) */ + } +cma_mbio_lcd; + +#define lcd_cmd lcd_bsr /* Command Register (W) */ + +/* 8-Position Configuration Switch */ +typedef + struct { + cma_mbio_reg dip_val; /* Dip Switch value (R) */ + } +cma_mbio_dipsw; + +#endif /* __ASSEMBLY__ */ diff --git a/cogent/cma10x/dipsw.c b/cogent/cma10x/dipsw.c new file mode 100644 index 0000000..2f57674 --- /dev/null +++ b/cogent/cma10x/dipsw.c @@ -0,0 +1,51 @@ +#include +#include "cma10x.h" +#include "dipsw.h" + +unsigned char +dipsw_raw(void) +{ + return cma_mbio_reg_read(&((cma_mbio_dipsw *)CMA_MBIO_DIPSW_BASE)->dip_val); +} + +unsigned char +dipsw_cooked(void) +{ + unsigned char val1, val2, mask1, mask2; + + val1 = dipsw_raw(); + + /* + * we want to mirror the bits because the low bit is switch 1 and high + * bit is switch 8 and also invert them because 1=off and 0=on, according + * to manual. + * + * this makes the value more intuitive i.e. + * - left most, or high, or top, bit is left most switch (1); + * - right most, or low, or bottom, bit is right most switch (8) + * - a set bit means "on" and a clear bit means "off" + */ + + val2 = 0; + for (mask1 = 1 << 7, mask2 = 1; mask1 > 0; mask1 >>= 1, mask2 <<= 1) + if ((val1 & mask1) == 0) + val2 |= mask2; + + return (val2); +} + +void +dipsw_init(void) +{ + unsigned char val, mask; + + val = dipsw_cooked(); + + printf("|"); + for (mask = 1 << 7; mask > 0; mask >>= 1) + if (val & mask) + printf("on |"); + else + printf("off|"); + printf("\n"); +} diff --git a/cogent/cma10x/dipsw.h b/cogent/cma10x/dipsw.h new file mode 100644 index 0000000..4f52fd4 --- /dev/null +++ b/cogent/cma10x/dipsw.h @@ -0,0 +1,3 @@ +extern unsigned char dipsw_raw(void); +extern unsigned char dipsw_cooked(void); +extern void dipsw_init(void); diff --git a/cogent/cma10x/lcd.c b/cogent/cma10x/lcd.c new file mode 100644 index 0000000..79240fe --- /dev/null +++ b/cogent/cma10x/lcd.c @@ -0,0 +1,234 @@ +// most of this is taken from the file +// hal/powerpc/cogent/current/src/hal_diag.c in the +// Cygnus eCos source. Here is the copyright notice: +// +//============================================================================= +// +// hal_diag.c +// +// HAL diagnostic output code +// +//============================================================================= +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg, jskov +// Contributors: nickg, jskov +// Date: 1999-03-23 +// Purpose: HAL diagnostic output +// Description: Implementations of HAL diagnostic output support. +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +//----------------------------------------------------------------------------- +// Cogent board specific LCD code + +#include +#include +#include "cma10x.h" +#include "lcd.h" + +extern int vsprintf(char *, const char *, va_list); + +static char lines[2][LCD_LINE_LENGTH+1]; +static int curline; +static int linepos; +static int heartbeat_active; +/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */ +/* pad to the right with spaces if necessary */ +static char init_line0[LCD_LINE_LENGTH+1] = "PPCBoot Cogent "; +static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000"; + +static inline unsigned char +lcd_read_status(cma_mbio_lcd *clp) +{ + /* read the Busy Status Register */ + return (cma_mbio_reg_read(&clp->lcd_bsr)); +} + +static inline void +lcd_wait_not_busy(cma_mbio_lcd *clp) +{ + /* + * wait for not busy + * Note: It seems that the LCD isn't quite ready to process commands + * when it clears the BUSY flag. Reading the status address an extra + * time seems to give it enough breathing room. + */ + + while (lcd_read_status(clp) & LCD_STAT_BUSY) + ; + + (void)lcd_read_status(clp); +} + +static inline void +lcd_write_command(cma_mbio_lcd *clp, unsigned char cmd) +{ + lcd_wait_not_busy(clp); + + /* write the Command Register */ + cma_mbio_reg_write(&clp->lcd_cmd, cmd); +} + +static inline void +lcd_write_data(cma_mbio_lcd *clp, unsigned char data) +{ + lcd_wait_not_busy(clp); + + /* write the Current Character Register */ + cma_mbio_reg_write(&clp->lcd_ccr, data); +} + +static inline void +lcd_dis(int addr, char *string) +{ + cma_mbio_lcd *clp = (cma_mbio_lcd *)CMA_MBIO_LCD_BASE; + int pos, linelen; + + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && addr == LCD_LINE0) + linelen--; + + lcd_write_command(clp, LCD_CMD_ADD + addr); + for (pos = 0; *string != '\0' && pos < linelen; pos++) + lcd_write_data(clp, *string++); +} + +void +lcd_init(void) +{ + cma_mbio_lcd *clp = (cma_mbio_lcd *)CMA_MBIO_LCD_BASE; + int i; + + /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */ + lcd_write_command(clp, LCD_CMD_MODE); + + /* turn the LCD display on */ + lcd_write_command(clp, LCD_CMD_DON); + + curline = 0; + linepos = 0; + + for (i = 0; i < LCD_LINE_LENGTH; i++) { + lines[0][i] = init_line0[i]; + lines[1][i] = init_line1[i]; + } + + lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0; + + lcd_dis(LCD_LINE0, lines[0]); + lcd_dis(LCD_LINE1, lines[1]); + + printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH); +} + +void +lcd_write_char(const char c) +{ + int i, linelen; + + /* ignore CR */ + if (c == '\r') + return; + + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && curline == 0) + linelen--; + + if (c == '\n') { + lcd_dis(LCD_LINE0, &lines[curline^1][0]); + lcd_dis(LCD_LINE1, &lines[curline][0]); + + /* Do a line feed */ + curline ^= 1; + linelen = LCD_LINE_LENGTH; + if (heartbeat_active && curline == 0) + linelen--; + linepos = 0; + + for (i = 0; i < linelen; i++) + lines[curline][i] = ' '; + + return; + } + + /* Only allow to be output if there is room on the LCD line */ + if (linepos < linelen) + lines[curline][linepos++] = c; +} + +void +lcd_flush(void) +{ + lcd_dis(LCD_LINE1, &lines[curline][0]); +} + +void +lcd_write_string(const char *s) +{ + char *p; + + for (p = (char *)s; *p != '\0'; p++) + lcd_write_char(*p); +} + +void +lcd_printf(const char *fmt, ...) +{ + va_list args; + char buf[CFG_PBSIZE]; + + va_start(args, fmt); + (void)vsprintf(buf, fmt, args); + va_end(args); + + lcd_write_string(buf); +} + +void +lcd_heartbeat(void) +{ + cma_mbio_lcd *clp = (cma_mbio_lcd *)CMA_MBIO_LCD_BASE; +#if 0 + static char rotchars[] = { '|', '/', '-', '\\' }; +#else + /* HD44780 Rom Code A00 has no backslash */ + static char rotchars[] = { '|', '/', '-', '\315' }; +#endif + static int rotator_index = 0; + + heartbeat_active = 1; + + /* write the address */ + lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1)); + + /* write the next char in the sequence */ + lcd_write_data(clp, rotchars[rotator_index]); + + if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0])) + rotator_index = 0; +} diff --git a/cogent/cma10x/lcd.h b/cogent/cma10x/lcd.h new file mode 100644 index 0000000..7af18c7 --- /dev/null +++ b/cogent/cma10x/lcd.h @@ -0,0 +1,84 @@ +// most of this is taken from the file +// hal/powerpc/cogent/current/src/hal_diag.c in the +// Cygnus eCos source. Here is the copyright notice: +// +//============================================================================= +// +// hal_diag.c +// +// HAL diagnostic output code +// +//============================================================================= +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg, jskov +// Contributors: nickg, jskov +// Date: 1999-03-23 +// Purpose: HAL diagnostic output +// Description: Implementations of HAL diagnostic output support. +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +// FEMA 162B 16 character x 2 line LCD + +// status register bit definitions +#define LCD_STAT_BUSY 0x80 // 1 = display busy +#define LCD_STAT_ADD 0x7F // bits 0-6 return current display address + +// command register definitions +#define LCD_CMD_RST 0x01 // clear entire display and reset display addr +#define LCD_CMD_HOME 0x02 // reset display address and reset any shifting +#define LCD_CMD_ECL 0x04 // move cursor left one pos on next data write +#define LCD_CMD_ESL 0x05 // shift display left one pos on next data write +#define LCD_CMD_ECR 0x06 // move cursor right one pos on next data write +#define LCD_CMD_ESR 0x07 // shift disp right one pos on next data write +#define LCD_CMD_DOFF 0x08 // display off, cursor off, blinking off +#define LCD_CMD_BL 0x09 // blink character at current cursor position +#define LCD_CMD_CUR 0x0A // enable cursor on +#define LCD_CMD_DON 0x0C // turn display on +#define LCD_CMD_CL 0x10 // move cursor left one position +#define LCD_CMD_SL 0x14 // shift display left one position +#define LCD_CMD_CR 0x18 // move cursor right one position +#define LCD_CMD_SR 0x1C // shift display right one position +#define LCD_CMD_MODE 0x38 // sets 8 bits, 2 lines, 5x7 characters +#define LCD_CMD_ACG 0x40 // bits 0-5 sets character generator address +#define LCD_CMD_ADD 0x80 // bits 0-6 sets display data addr to line 1 + + +// LCD status values +#define LCD_OK 0x00 +#define LCD_ERR 0x01 + +#define LCD_LINE0 0x00 +#define LCD_LINE1 0x40 + +#define LCD_LINE_LENGTH 16 + +extern void lcd_init(void); +extern void lcd_write_char(const char); +extern void lcd_flush(void); +extern void lcd_write_string(const char *); +extern void lcd_printf(const char *, ...); diff --git a/cogent/cma10x/parallel.c b/cogent/cma10x/parallel.c new file mode 100644 index 0000000..a03c0f1 --- /dev/null +++ b/cogent/cma10x/parallel.c @@ -0,0 +1,3 @@ +/* parallel not implemented yet */ + +int cma_parallel_not_implemented = 1; diff --git a/cogent/cma10x/parallel.h b/cogent/cma10x/parallel.h new file mode 100644 index 0000000..664ae4a --- /dev/null +++ b/cogent/cma10x/parallel.h @@ -0,0 +1,3 @@ +/* parallel not implemented yet */ + +extern int cma_parallel_not_implemented; diff --git a/cogent/cma10x/rtc.c b/cogent/cma10x/rtc.c new file mode 100644 index 0000000..ace9193 --- /dev/null +++ b/cogent/cma10x/rtc.c @@ -0,0 +1,3 @@ +/* rtc not implemented yet */ + +int cma_rtc_not_implemented = 1; diff --git a/cogent/cma10x/rtc.h b/cogent/cma10x/rtc.h new file mode 100644 index 0000000..4b55bd2 --- /dev/null +++ b/cogent/cma10x/rtc.h @@ -0,0 +1,3 @@ +/* rtc not implemented yet */ + +extern int cma_rtc_not_implemented; diff --git a/cogent/cma10x/serial.c b/cogent/cma10x/serial.c new file mode 100644 index 0000000..c764e09 --- /dev/null +++ b/cogent/cma10x/serial.c @@ -0,0 +1,153 @@ +/* + * Simple serial driver for Cogent CMA10x motherboard serial port A + * for use during boot + */ + +#include + +#if defined(CONFIG_8xx_CONS_NONE) + +#include "cma10x.h" +#include "serial.h" + +void +serial_init(ulong cpu_clock, int baudrate) +{ + cma_mbio_serial *sAp = (cma_mbio_serial *)CMA_MBIO_SERIALA_BASE; + + cma_mbio_reg_write(&sAp->ser_ier, 0x00); /* turn off interrupts */ + serial_setbrg(cpu_clock, baudrate); + cma_mbio_reg_write(&sAp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */ + cma_mbio_reg_write(&sAp->ser_mcr, 0x03); /* RTS/DTR */ + cma_mbio_reg_write(&sAp->ser_fcr, 0x07); /* Clear & enable FIFOs */ +} + +void +serial_setbrg(ulong cpu_clock, int baudrate) +{ + cma_mbio_serial *sAp = (cma_mbio_serial *)CMA_MBIO_SERIALA_BASE; + unsigned int divisor; + unsigned char lcr; + + if ((divisor = br_to_div(baudrate)) == 0) + divisor = DEFDIV; + + lcr = cma_mbio_reg_read(&sAp->ser_lcr); + cma_mbio_reg_write(&sAp->ser_lcr, lcr|0x80);/* Access baud rate(set DLAB)*/ + cma_mbio_reg_write(&sAp->ser_brl, divisor & 0xff); + cma_mbio_reg_write(&sAp->ser_brh, (divisor >> 8) & 0xff); + cma_mbio_reg_write(&sAp->ser_lcr, lcr); /* unset DLAB */ +} + +void +serial_putc(const char c) +{ + cma_mbio_serial *sAp = (cma_mbio_serial *)CMA_MBIO_SERIALA_BASE; + + if (c == '\n') + serial_putc('\r'); + + while ((cma_mbio_reg_read(&sAp->ser_lsr) & LSR_THRE) == 0) + ; + + cma_mbio_reg_write(&sAp->ser_thr, c); +} + +void +serial_putstr(const char *s) +{ + while (*s != '\0') + serial_putc(*s++); +} + +int +serial_getc(void) +{ + cma_mbio_serial *sAp = (cma_mbio_serial *)CMA_MBIO_SERIALA_BASE; + + while ((cma_mbio_reg_read(&sAp->ser_lsr) & LSR_DR) == 0) + ; + + return ((int)cma_mbio_reg_read(&sAp->ser_rhr) & 0x7f); +} + +int +serial_tstc(void) +{ + cma_mbio_serial *sAp = (cma_mbio_serial *)CMA_MBIO_SERIALA_BASE; + + return ((cma_mbio_reg_read(&sAp->ser_lsr) & LSR_DR) != 0); +} + +#endif /* CONFIG_8xx_CONS_NONE */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + +void +kgdb_serial_init(void) +{ + cma_mbio_serial *sBp = (cma_mbio_serial *)CMA_MBIO_SERIALB_BASE; + unsigned int divisor; + + if ((divisor = br_to_div(CONFIG_KGDB_BAUDRATE)) == 0) + divisor = DEFDIV; + + cma_mbio_reg_write(&sBp->ser_ier, 0x00); /* turn off interrupts */ + cma_mbio_reg_write(&sBp->ser_lcr, 0x80); /* Access baud rate(set DLAB)*/ + cma_mbio_reg_write(&sBp->ser_brl, divisor & 0xff); + cma_mbio_reg_write(&sBp->ser_brh, (divisor >> 8) & 0xff); + cma_mbio_reg_write(&sBp->ser_lcr, 0x03); /* 8 data, 1 stop, no parity */ + cma_mbio_reg_write(&sBp->ser_mcr, 0x03); /* RTS/DTR */ + cma_mbio_reg_write(&sBp->ser_fcr, 0x07); /* Clear & enable FIFOs */ + + printf("[on cma10x serial port B] "); +} + +void +putDebugChar(int c) +{ + cma_mbio_serial *sBp = (cma_mbio_serial *)CMA_MBIO_SERIALB_BASE; + + while ((cma_mbio_reg_read(&sBp->ser_lsr) & LSR_THRE) == 0) + ; + + cma_mbio_reg_write(&sBp->ser_thr, c & 0xff); +} + +void +putDebugStr(const char *str) +{ + while (*str != '\0') { + if (*str == '\n') + putDebugChar('\r'); + putDebugChar(*str++); + } +} + +int +getDebugChar(void) +{ + cma_mbio_serial *sBp = (cma_mbio_serial *)CMA_MBIO_SERIALB_BASE; + + while ((cma_mbio_reg_read(&sBp->ser_lsr) & LSR_DR) == 0) + ; + + return ((int)cma_mbio_reg_read(&sBp->ser_rhr) & 0x7f); +} + +void +kgdb_interruptible(int yes) +{ + cma_mbio_serial *sBp = (cma_mbio_serial *)CMA_MBIO_SERIALB_BASE; + + if (yes == 1) { + printf("kgdb: turning serial ints on\n"); + cma_mbio_reg_write(&sBp->ser_ier, 0xf); + } + else { + printf("kgdb: turning serial ints off\n"); + cma_mbio_reg_write(&sBp->ser_ier, 0x0); + } +} + +#endif /* CFG_CMD_KGDB */ diff --git a/cogent/cma10x/serial.h b/cogent/cma10x/serial.h new file mode 100644 index 0000000..0e78074 --- /dev/null +++ b/cogent/cma10x/serial.h @@ -0,0 +1,15 @@ +/* Line Status Register bits */ +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + +#define CLKRATE 3686400 /* cma10x serial clk = 3.6864MHz */ +#define DEFDIV 1 /* default to 230400 bps */ + +#define br_to_div(br) (CLKRATE / (16 * (br))) +#define div_to_br(div) (CLKRATE / (16 * (div))) diff --git a/cogent/cma302/cma302.h b/cogent/cma302/cma302.h new file mode 100644 index 0000000..1a54926 --- /dev/null +++ b/cogent/cma302/cma302.h @@ -0,0 +1,274 @@ +/* + * Cogent CMA302 I/O Module - Flash Memory and PS/2 keyboard + mouse + */ + +/**************** DEFINES for H8542B Keyboard/Mouse Controller ***************/ + +/* + * note the auxillary port is used to control the mouse + */ + +/* 8542B Commands (Sent to the Command Port) */ +#define HT8542_CMD_SET_BYTE 0x60 /* Set the command byte */ +#define HT8542_CMD_GET_BYTE 0x20 /* Get the command byte */ +#define HT8542_CMD_KBD_OBUFF 0xD2 /* Write to HT8542 Kbd Output Buffer */ +#define HT8542_CMD_AUX_OBUFF 0xD3 /* Write to HT8542 Mse Output Buffer */ +#define HT8542_CMD_AUX_WRITE 0xD4 /* Write to Mouse Port */ +#define HT8542_CMD_AUX_OFF 0xA7 /* Disable Mouse Port */ +#define HT8542_CMD_AUX_ON 0xA8 /* Re-Enable Mouse Port */ +#define HT8542_CMD_AUX_TEST 0xA9 /* Test for the presence of a Mouse */ +#define HT8542_CMD_DIAG 0xAA /* Start Diagnostics */ +#define HT8542_CMD_KBD_TEST 0xAB /* Test for presence of a keyboard */ +#define HT8542_CMD_KBD_OFF 0xAD /* Disable Kbd Port (use KBD_DAT_ON) */ +#define HT8542_CMD_KBD_ON 0xAE /* Enable Kbd Port (use KBD_DAT_OFF) */ + +/* HT8542B cmd byte set by KBD_CMD_SET_BYTE and retrieved by KBD_CMD_GET_BYTE */ +#define HT8542_CMD_BYTE_TRANS 0x40 +#define HT8542_CMD_BYTE_AUX_OFF 0x20 /* 1 = mse port disabled, 0 = enabled */ +#define HT8542_CMD_BYTE_KBD_OFF 0x10 /* 1 = kbd port disabled, 0 = enabled */ +#define HT8542_CMD_BYTE_OVER 0x08 /* 1 = override keyboard lock */ +#define HT8542_CMD_BYTE_RES 0x04 /* reserved */ +#define HT8542_CMD_BYTE_AUX_INT 0x02 /* 1 = enable mouse interrupt */ +#define HT8542_CMD_BYTE_KBD_INT 0x01 /* 1 = enable keyboard interrupt */ + +/* Keyboard Commands (Sent to the Data Port) */ +#define KBD_CMD_LED 0xED /* Set Keyboard LEDS with next byte */ +#define KBD_CMD_ECHO 0xEE /* Echo - we get 0xFA, 0xEE back */ +#define KBD_CMD_MODE 0xF0 /* set scan code mode with next byte */ +#define KBD_CMD_ID 0xF2 /* get keyboard/mouse ID */ +#define KBD_CMD_RPT 0xF3 /* Set Repeat Rate and Delay 2nd Byte */ +#define KBD_CMD_ON 0xF4 /* Enable keyboard */ +#define KBD_CMD_OFF 0xF5 /* Disables Scanning, Resets to Def */ +#define KBD_CMD_DEF 0xF6 /* Reverts kbd to default settings */ +#define KBD_CMD_RST 0xFF /* Reset - should get 0xFA, 0xAA back */ + +/* Set LED second bit defines */ +#define KBD_CMD_LED_SCROLL 0x01 /* Set SCROLL LOCK LED on */ +#define KBD_CMD_LED_NUM 0x02 /* Set NUM LOCK LED on */ +#define KBD_CMD_LED_CAPS 0x04 /* Set CAPS LOCK LED on */ + +/* Set Mode second byte defines */ +#define KBD_CMD_MODE_STAT 0x00 /* get current scan code mode */ +#define KBD_CMD_MODE_SCAN1 0x01 /* set mode to scan code 1 */ +#define KBD_CMD_MODE_SCAN2 0x02 /* set mode to scan code 2 */ +#define KBD_CMD_MODE_SCAN3 0x03 /* set mode to scan code 3 */ + +/* Keyboard/Mouse ID Codes */ +#define KBD_CMD_ID_1ST 0xAB /* 1st byte is 0xAB, 2nd is actual ID */ +#define KBD_CMD_ID_KBD 0x83 /* Keyboard */ +#define KBD_CMD_ID_MOUSE 0x00 /* Mouse */ + +/* Keyboard Data Return Defines */ +#define KBD_STAT_OVER 0x00 /* Buffer Overrun */ +#define KBD_STAT_DIAG_OK 0x55 /* Internal Self Test OK */ +#define KBD_STAT_RST_OK 0xAA /* Reset Complete */ +#define KBD_STAT_ECHO 0xEE /* Echo Command Return */ +#define KBD_STAT_BRK 0xF0 /* Prefix for Break Key Code */ +#define KBD_STAT_ACK 0xFA /* Received after all commands */ +#define KBD_STAT_DIAG_FAIL 0xFD /* Internal Self Test Failed */ +#define KBD_STAT_RESEND 0xFE /* Resend Last Command */ + +/* HT8542B Status Register Bit Defines */ +#define HT8542_STAT_OBF 0x01 /* 1 = output buffer is full */ +#define HT8542_STAT_IBF 0x02 /* 1 = input buffer is full */ +#define HT8542_STAT_SYS 0x04 /* system flag - unused */ +#define HT8542_STAT_CMD 0x08 /* 1 = cmd in input buffer, 0 = data */ +#define HT8542_STAT_INH 0x10 /* 1 = Inhibit - unused */ +#define HT8542_STAT_TX 0x20 /* 1 = Transmit Timeout has occured */ +#define HT8542_STAT_RX 0x40 /* 1 = Receive Timeout has occured */ +#define HT8542_STAT_PERR 0x80 /* 1 = Parity Error from Keyboard */ + +/******************* DEFINES for 28F008S5 FLASH chip *************************/ + +/* register addresses, valid only following a CHIP_CMD_RD_ID command */ +#define CHIP_ADDR_MAN 0x00000 /* manufacturer's id */ +#define CHIP_ADDR_DEV 0x00001 /* device id */ +#define CHIP_ADDR_CFGM 0x00003 /* master lock configuration */ +#define CHIP_ADDR_CFG0 0x00002 /* block lock configuration */ +#define CHIP_ADDR_CFG1 0x10002 /* " */ +#define CHIP_ADDR_CFG2 0x20002 /* " */ +#define CHIP_ADDR_CFG3 0x30002 /* " */ +#define CHIP_ADDR_CFG4 0x40002 /* " */ +#define CHIP_ADDR_CFG5 0x50002 /* " */ +#define CHIP_ADDR_CFG6 0x60002 /* " */ +#define CHIP_ADDR_CFG7 0x70002 /* " */ +#define CHIP_ADDR_CFG8 0x80002 /* " */ +#define CHIP_ADDR_CFG9 0x90002 /* " */ +#define CHIP_ADDR_CFG10 0xA0002 /* " */ +#define CHIP_ADDR_CFG11 0xB0002 /* " */ +#define CHIP_ADDR_CFG12 0xC0002 /* " */ +#define CHIP_ADDR_CFG13 0xD0002 /* " */ +#define CHIP_ADDR_CFG14 0xE0002 /* " */ +#define CHIP_ADDR_CFG15 0xF0002 /* " */ + +/* Commands */ +#define CHIP_CMD_RST 0xFF /* reset flash */ +#define CHIP_CMD_RD_ID 0x90 /* read the id and lock bits */ +#define CHIP_CMD_RD_STAT 0x70 /* read the status register */ +#define CHIP_CMD_CLR_STAT 0x50 /* clear the staus register */ +#define CHIP_CMD_ERASE1 0x20 /* first word for block erase */ +#define CHIP_CMD_ERASE2 0xD0 /* second word for block erase */ +#define CHIP_CMD_PROG 0x40 /* program word command */ +#define CHIP_CMD_LOCK 0x60 /* first word for all lock commands */ +#define CHIP_CMD_SET_LOCK_BLK 0x01 /* 2nd word for set block lock bit */ +#define CHIP_CMD_SET_LOCK_MSTR 0xF1 /* 2nd word for set master lock bit */ +#define CHIP_CMD_CLR_LOCK_BLK 0xD0 /* 2nd word for clear block lock bit */ + +/* status register bits */ +#define CHIP_STAT_DPS 0x02 /* Device Protect Status */ +#define CHIP_STAT_PSS 0x04 /* Program Suspend Status */ +#define CHIP_STAT_VPPS 0x08 /* VPP Status */ +#define CHIP_STAT_PSLBS 0x10 /* Program and Set Lock Bit Status */ +#define CHIP_STAT_ECLBS 0x20 /* Erase and Clear Lock Bit Status */ +#define CHIP_STAT_ESS 0x40 /* Erase Suspend Status */ +#define CHIP_STAT_RDY 0x80 /* Write State Machine Status, 1=rdy */ + +#define CHIP_STAT_ERR (CHIP_STAT_VPPS|CHIP_STAT_DPS|\ + CHIP_STAT_ECLBS|CHIP_STAT_PSLBS) + +/* ID and Lock Configuration */ +#define CHIP_RD_ID_LOCK 0x01 /* Bit 0 of each byte */ +#define CHIP_RD_ID_MAN 0x89 /* Manufacturer code = 0x89 */ +#define CHIP_RD_ID_DEV 0xA6 /* Device code = 0xA6, 28F008S5 */ + +/* dimensions */ +#define CHIP_NBLOCKS 16 /* a 28F008S5 consists of 16 blocks */ +#define CHIP_BLOCKSZ (64*1024) /* of 64Kbyte each */ +#define CHIP_SIZE (CHIP_BLOCKSZ * CHIP_NBLOCKS) + +/********************* DEFINES for Cogent CMA302 *****************************/ + +/* + * Quoted from the CMA302 manual: + * + * Although the CMA302 supports 64-bit reads, all writes must be done with + * word size only. When programming the CMA302, the FLASH devices appear as 2 + * banks of interleaved, 32-bit wide FLASH. Each 32-bit word consists of four + * 28F008S5 devices. The first bank is accessed when the word address is even, + * while the second bank is accessed when the word address is odd. This must + * be taken into account when programming the desired word. Also, when locking + * blocks, software must lock both banks. The CMA302 does not directly support + * byte writing. Programming and/or erasing individual bytes is done with + * selective use of the Write Command. By not placing the Write Command value + * on a particular byte lane, that byte will not be written with the following + * Write Data. Also, remember that within a byte lane (i.e. D0-7), there are + * two 28F008S5 devices, one for each bank or every other word. + * + * End quote. + * + * Each 28F008S5 is 8Mbit, with 8 bit wide data. i.e. each is 1Mbyte. The + * chips are arranged on the CMA302 in multiples of two banks, each bank having + * 4 chips. Each bank must be accessed as a single 32 bit wide device (i.e. + * aligned on a 32 bit boundary), with each byte lane within the 32 bits (0-3) + * going to each of the 4 chips and the word address selecting the bank, even + * being the low bank and odd the high bank. For 64bit reads, both banks are + * read simultaneously with the second bank on byte lanes 4-7. Each 28F008S5 + * consists of 16 64Kbyte "block"s. Before programming a byte, the block that + * the byte resides within must be erased. So if you want to program contiguous + * memory locations, you must erase all 8 chips at the same time. i.e. the + * flash on the CMA302 can be viewed as a number of 512Kbyte blocks. + * + * Note: I am going to treat banks as 8 Mbytes (1Meg of 64bit words), whereas + * the example code treats them as a pair of interleaved 1 Mbyte x 32bit banks. + */ + +typedef unsigned long flash_word_t; /* 32 or 64 bit unsigned integer */ +typedef volatile flash_word_t *flash_addr_t; +typedef unsigned long flash_size_t; /* want this big - at least 32 bit */ + +/* layout of banks on cma302 board */ +#define BANK_WIDTH 8 /* each bank is 8 chips wide */ +#define BANK_SHIFT 3 /* (1 << BANK_SHIFT) == BANK_WIDTH */ +#define BANK_NBLOCKS CHIP_NBLOCKS +#define BANK_BLOCKSZ (CHIP_BLOCKSZ * BANK_WIDTH) +#define BANK_SIZE (CHIP_SIZE * BANK_WIDTH) + +#define MAX_BANKS 2 /* up to 2 banks (8M each) on CMA302 */ + +/* align addresses and sizes to bank boundaries */ +#define BANK_ALIGN_ADDR(a) ((flash_addr_t)\ + ((flash_size_t)(a) & ~(BANK_WIDTH - 1))) +#define BANK_ALIGN_SIZE(s) ((flash_size_t)BANK_ALIGN_ADDR((flash_size_t)\ + (s) + (BANK_WIDTH - 1))) + +/* align addresses and sizes to block boundaries */ +#define BLOCK_ALIGN_ADDR(a) ((flash_addr_t)\ + ((flash_size_t)(a) & ~(BANK_BLOCKSZ - 1))) +#define BLOCK_ALIGN_SIZE(s) ((flash_size_t)BLOCK_ALIGN_ADDR((flash_size_t)\ + (s) + (BANK_BLOCKSZ - 1))) + +/* add a byte offset to a flash address */ +#define ADD_BYTEOFF_ADDR(a,o) (flash_addr_t)((flash_size_t)(a) + (o)) + +/* adjust a bank address with a chip register offset */ +#define CHIP_TO_BANK_ADDR(a,o) ADD_BYTEOFF_ADDR((a), (o) << BANK_SHIFT) + +#define BANK_BASE_ADDR(a,b) ADD_BYTEOFF_ADDR((a), \ + (flash_size_t)(b) * BANK_SIZE) +#define BANK_NEXT_WORD_ADDR(a) ADD_BYTEOFF_ADDR((a), BANK_WIDTH) +#define BANK_NEXT_BLOCK_ADDR(a) ADD_BYTEOFF_ADDR((a), BANK_BLOCKSZ) +#define BANK_NEXT_BANK_ADDR(a) ADD_BYTEOFF_ADDR((a), BANK_SIZE) + +/* make a bank representation for each chip address */ + +#define BANK_ADDR_MAN(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_MAN) +#define BANK_ADDR_DEV(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_DEV) +#define BANK_ADDR_CFGM(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFGM) +#define BANK_ADDR_CFG0(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG0) +#define BANK_ADDR_CFG1(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG1) +#define BANK_ADDR_CFG2(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG2) +#define BANK_ADDR_CFG3(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG3) +#define BANK_ADDR_CFG4(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG4) +#define BANK_ADDR_CFG5(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG5) +#define BANK_ADDR_CFG6(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG6) +#define BANK_ADDR_CFG7(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG7) +#define BANK_ADDR_CFG8(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG8) +#define BANK_ADDR_CFG9(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG9) +#define BANK_ADDR_CFG10(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG10) +#define BANK_ADDR_CFG11(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG11) +#define BANK_ADDR_CFG12(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG12) +#define BANK_ADDR_CFG13(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG13) +#define BANK_ADDR_CFG14(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG14) +#define BANK_ADDR_CFG15(a) CHIP_TO_BANK_ADDR((a), CHIP_ADDR_CFG15) + +/* + * replicate a chip cmd/stat/rd value into each byte position within a word + * so that multiple chips are accessed in a single word i/o operation + * + * this must be as wide as the flash_word_t type + */ +#define REPLICATE_TO_WORD(o) (((unsigned long)(o) << 24) | \ + ((unsigned long)(o) << 16) | \ + ((unsigned long)(o) << 8) | \ + (unsigned long)(o)) + +/* make a bank representation for each chip cmd/stat/rd value */ + +/* Commands */ +#define BANK_CMD_RST REPLICATE_TO_WORD(CHIP_CMD_RST) +#define BANK_CMD_RD_ID REPLICATE_TO_WORD(CHIP_CMD_RD_ID) +#define BANK_CMD_RD_STAT REPLICATE_TO_WORD(CHIP_CMD_RD_STAT) +#define BANK_CMD_CLR_STAT REPLICATE_TO_WORD(CHIP_CMD_CLR_STAT) +#define BANK_CMD_ERASE1 REPLICATE_TO_WORD(CHIP_CMD_ERASE1) +#define BANK_CMD_ERASE2 REPLICATE_TO_WORD(CHIP_CMD_ERASE2) +#define BANK_CMD_PROG REPLICATE_TO_WORD(CHIP_CMD_PROG) +#define BANK_CMD_LOCK REPLICATE_TO_WORD(CHIP_CMD_LOCK) +#define BANK_CMD_SET_LOCK_BLK REPLICATE_TO_WORD(CHIP_CMD_SET_LOCK_BLK) +#define BANK_CMD_SET_LOCK_MSTR REPLICATE_TO_WORD(CHIP_CMD_SET_LOCK_MSTR) +#define BANK_CMD_CLR_LOCK_BLK REPLICATE_TO_WORD(CHIP_CMD_CLR_LOCK_BLK) + +/* status register bits */ +#define BANK_STAT_DPS REPLICATE_TO_WORD(CHIP_STAT_DPS) +#define BANK_STAT_PSS REPLICATE_TO_WORD(CHIP_STAT_PSS) +#define BANK_STAT_VPPS REPLICATE_TO_WORD(CHIP_STAT_VPPS) +#define BANK_STAT_PSLBS REPLICATE_TO_WORD(CHIP_STAT_PSLBS) +#define BANK_STAT_ECLBS REPLICATE_TO_WORD(CHIP_STAT_ECLBS) +#define BANK_STAT_ESS REPLICATE_TO_WORD(CHIP_STAT_ESS) +#define BANK_STAT_RDY REPLICATE_TO_WORD(CHIP_STAT_RDY) + +#define BANK_STAT_ERR REPLICATE_TO_WORD(CHIP_STAT_ERR) + +/* ID and Lock Configuration */ +#define BANK_RD_ID_LOCK REPLICATE_TO_WORD(CHIP_RD_ID_LOCK) +#define BANK_RD_ID_MAN REPLICATE_TO_WORD(CHIP_RD_ID_MAN) +#define BANK_RD_ID_DEV REPLICATE_TO_WORD(CHIP_RD_ID_DEV) diff --git a/cogent/cma302/flash.c b/cogent/cma302/flash.c new file mode 100644 index 0000000..d7b95e3 --- /dev/null +++ b/cogent/cma302/flash.c @@ -0,0 +1,777 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include "cma302.h" + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Functions + */ +static int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); +static int write_word (flash_info_t *info, ulong dest, ulong data); +static int flash_protect (int flag, ulong from, ulong to, flash_info_t *info); + +/*----------------------------------------------------------------------- + * Protection Flags: + */ +#define FLAG_PROTECT_SET 0x01 +#define FLAG_PROTECT_CLEAR 0x02 + +/*----------------------------------------------------------------------- + */ + + +/* + * probe for the existence of flash at address "addr" + * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id + */ +static int +flash_probe_word(flash_addr_t addr) +{ + /* reset the flash */ + *addr = BANK_CMD_RST; + + /* check the manufacturer id */ + *addr = BANK_CMD_RD_ID; + if (*BANK_ADDR_MAN(addr) != BANK_RD_ID_MAN) + return 1; + + /* check the device id */ + *addr = BANK_CMD_RD_ID; + if (*BANK_ADDR_DEV(addr) != BANK_RD_ID_DEV) + return 2; + +#ifdef FLASH_DEBUG + printf("\nMaster Lock Config = 0x%08lx\n", *BANK_ADDR_CFGM(addr)); + printf("Block 0 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG0(addr)); + printf("Block 1 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG1(addr)); + printf("Block 2 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG2(addr)); + printf("Block 3 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG3(addr)); + printf("Block 4 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG4(addr)); + printf("Block 5 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG5(addr)); + printf("Block 6 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG6(addr)); + printf("Block 7 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG7(addr)); + printf("Block 8 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG8(addr)); + printf("Block 9 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG9(addr)); + printf("Block 10 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG10(addr)); + printf("Block 11 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG11(addr)); + printf("Block 12 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG12(addr)); + printf("Block 13 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG13(addr)); + printf("Block 14 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG14(addr)); + printf("Block 15 Lock Config = 0x%08lx\n", *BANK_ADDR_CFG15(addr)); +#endif + + /* reset the flash again */ + *addr = BANK_CMD_RST; + + return 0; +} + +unsigned long +flash_init(void) +{ + flash_addr_t addr, eaddr; + unsigned long total; + int i, nbanks; + + /* Init: no FLASHes known */ + for (i=0; i= CFG_MAX_FLASH_BANKS) { + printf("[more flash available than config allows!] "); + break; + } + + /* fill in info for this bank */ + flash_info[nbanks].size = BANK_SIZE; + flash_info[nbanks].sector_count = BANK_NBLOCKS; + flash_info[nbanks].flash_id = FLASH_MAN_INTEL|FLASH_28F008S5; + addrb = addr; + for (i = 0; i < BANK_NBLOCKS; i++) { + flash_info[nbanks].start[i] = (ulong)addrb; + flash_info[nbanks].protect[i] = 0; + addrb = BANK_NEXT_BLOCK_ADDR(addrb); + } + + total += BANK_SIZE; + nbanks++; + + addr = BANK_NEXT_BANK_ADDR(addr); + } + +out: + if (nbanks == 0) { + printf( + "\nERROR: flash_init: no flash found at address 0x%08lx\n", + (unsigned long)CFG_FLASH_BASE); + hang(); + } + + /* protect monitor and environment */ +#if CFG_MONITOR_BASE == CFG_FLASH_BASE + (void)flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + +#if defined(CFG_FLASH_ENV_ADDR) + (void)flash_protect(FLAG_PROTECT_SET, + CFG_FLASH_ENV_ADDR, +#if defined(CFG_FLASH_ENV_BUF) + CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1, +#else + CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_SIZE - 1, +#endif + &flash_info[0]); +#endif + + return total; +} + +/*----------------------------------------------------------------------- + * Check or set protection status for monitor sectors + * + * The monitor always occupies the _first_ part of the _first_ Flash bank. + */ +static int +flash_protect(int flag, ulong from, ulong to, flash_info_t *info) +{ + ulong b_end = info->start[0] + info->size - 1; /* bank end address */ + int rc = 0; + int first = -1; + int last = -1; + int i; + + if (to < info->start[0]) { + return (0); + } + + for (i=0; isector_count; ++i) { + ulong end; /* last address in current sect */ + short s_end; + + s_end = info->sector_count - 1; + + end = (i == s_end) ? b_end : info->start[i + 1] - 1; + + if (from > end) { + continue; + } + if (to < info->start[i]) { + continue; + } + + if (from == info->start[i]) { + first = i; + if (last < 0) { + last = s_end; + } + } + if (to == end) { + last = i; + if (first < 0) { + first = 0; + } + } + } + + for (i=first; i<=last; ++i) { + if (flag & FLAG_PROTECT_CLEAR) { + info->protect[i] = 0; + } else if (flag & FLAG_PROTECT_SET) { + info->protect[i] = 1; + } + if (info->protect[i]) { + rc = 1; + } + } + return (rc); +} + + +/*----------------------------------------------------------------------- + */ +void +flash_print_info(flash_info_t *info) +{ + int i; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_INTEL: printf ("INTEL "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_28F008S5: printf ("28F008S5\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; isector_count; ++i) { + if ((i % 4) == 0) + printf ("\n "); + printf (" %2d - %08lX%s", i, + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +void +flash_erase(flash_info_t *info, int s_first, int s_last, bd_t *bd) +{ + int flag, prot, sect, errcount; + ulong start, now, last; +#if defined(CFG_CMA302_PARALLEL_ERASE) + int alldone; + uchar done[CFG_MAX_FLASH_SECT]; +#endif + +#ifdef FLASH_DEBUG + printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" + " Bank # %d: ", s_last - s_first + 1, s_first, s_last, + (info - flash_info) + 1); + flash_print_info(info); + printf("0x%08lx BANK_CMD_PROG\n", BANK_CMD_PROG); + printf("0x%08lx BANK_CMD_ERASE1\n", BANK_CMD_ERASE1); + printf("0x%08lx BANK_CMD_ERASE2\n", BANK_CMD_ERASE2); + printf("0x%08lx BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT); + printf("0x%08lx BANK_CMD_RST\n", BANK_CMD_RST); + printf("0x%08lx BANK_STAT_RDY\n", BANK_STAT_RDY); + printf("0x%08lx BANK_STAT_ERR\n", BANK_STAT_ERR); +#endif + + 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; + } + + if (info->flash_id != (FLASH_MAN_INTEL|FLASH_28F008S5)) { + printf ("Flash type must be Intel 28F008S5 - aborted\n"); + return; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf("- Warning: %d protected sector%s will not be erased!\n", + prot, (prot > 1 ? "s" : "")); + } + +#if defined(CFG_CMA302_PARALLEL_ERASE) + + /* + * erase all the unprotected sectors in parallel + * + * Quote from the Intel 28F008S5 manual, section 4.5 "Block + * Erase Command", "Erase is executed one block at a time ...". + * + * I take this to mean that you cannot erase multiple blocks + * in parallel. But I'll leave this code here for reference... + */ + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + flash_addr_t addrw, eaddrw; + + addrw = (flash_addr_t)info->start[sect]; + eaddrw = BANK_NEXT_WORD_ADDR(addrw); + + while (addrw < eaddrw) { + *addrw = BANK_CMD_ERASE1; + *addrw = BANK_CMD_ERASE2; + addrw++; + } + + done[sect] = 0; + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000, bd->bi_intfreq); + + start = get_timer (0); + last = 0; + errcount = 0; + + do { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + serial_putc ('.'); + last = now; + } + + /* see if all sectors are finished */ + alldone = 1; + + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0 && !done[sect]) { + flash_addr_t addrw, eaddrw; + int sectdone, secterr; + + addrw = (flash_addr_t)info->start[sect]; + eaddrw = BANK_NEXT_WORD_ADDR(addrw); + + sectdone = 1; + secterr = 0; + + while (addrw < eaddrw) { + flash_word_t stat = *addrw; + + if ((stat & BANK_STAT_RDY) + != BANK_STAT_RDY) + sectdone = 0; + else if ((stat & BANK_STAT_ERR) != 0) { + printf(" failed on sector %d " + "(stat = 0x%08lx) at " + "address 0x%08lx\n", + sect, stat, + (unsigned long)addrw); + *addrw = BANK_CMD_CLR_STAT; + secterr = 1; + } + + addrw++; + } + + if (secterr) + errcount++; + + if (sectdone || secterr) + done[sect] = 1; + else + alldone = 0; + } + } + + } while (!alldone); + + if (errcount > 0) + printf (" failed (%d sector%s had errors)\n", + errcount, errcount > 1 ? "s" : ""); + else + printf (" done\n"); + +#else /* CFG_CMA302_PARALLEL_ERASE */ + + /* erase each unprotected sector sequentially */ + + start = get_timer (0); + last = 0; + errcount = 0; + + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + flash_addr_t addrw, saddrw, eaddrw; + int sectdone; + ulong estart; + + saddrw = (flash_addr_t)info->start[sect]; + eaddrw = BANK_NEXT_WORD_ADDR(saddrw); + +#ifdef FLASH_DEBUG + printf("erasing sector %d, start addr = 0x%08lx " + "(bank next word addr = 0x%08lx)\n", sect, + (unsigned long)saddrw, (unsigned long)eaddrw); +#endif + + /* Disable intrs which might cause a timeout here */ + flag = disable_interrupts(); + + for (addrw = saddrw; addrw < eaddrw; addrw++) { +#ifdef FLASH_DEBUG + printf(" writing erase cmd to addr 0x%08lx\n", + (unsigned long)addrw); +#endif + *addrw = BANK_CMD_ERASE1; + *addrw = BANK_CMD_ERASE2; + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000, bd->bi_intfreq); + + estart = get_timer(start); + + do { + now = get_timer(start); + + if (now - estart > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout (sect %d, " + "addr 0x%08lx)\n", sect, + (unsigned long)addrw); + errcount = 1; + break; + } + +#ifndef FLASH_DEBUG + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + serial_putc ('.'); + last = now; + } +#endif + + sectdone = 1; + + for (addrw = saddrw; addrw < eaddrw; addrw++) { + flash_word_t stat = *addrw; + +#ifdef FLASH_DEBUG + printf(" checking status at addr " + "0x%08lx [0x%08lx]\n", + (unsigned long)addrw, stat); +#endif + if ((stat & BANK_STAT_RDY) + != BANK_STAT_RDY) + sectdone = 0; + else if ((stat & BANK_STAT_ERR) != 0) { + printf(" failed on sector %d " + "(stat = 0x%08lx) at " + "address 0x%08lx\n", + sect, stat, + (unsigned long)addrw); + *addrw = BANK_CMD_CLR_STAT; + errcount = 1; + } + } + + } while (!sectdone); + + if (errcount) + break; + } + } + + if (errcount > 0) + printf (" failed\n"); + else + printf (" done\n"); + +#endif /* CFG_CMA302_PARALLEL_ERASE */ + + /* reset to read mode */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + flash_addr_t addrw, eaddrw; + + addrw = (flash_addr_t)info->start[sect]; + eaddrw = BANK_NEXT_WORD_ADDR(addrw); + + while (addrw < eaddrw) { +#ifdef FLASH_DEBUG + printf(" writing reset cmd to addr 0x%08lx\n", + (unsigned long)addrw); +#endif + *addrw = BANK_CMD_RST; + addrw++; + } + } + } +} + +/*----------------------------------------------------------------------- + */ + +flash_info_t * +addr2info(ulong addr) +{ + flash_info_t *info; + int i; + + for (i=0, info=&flash_info[0]; i= info->start[0]) && + (addr < (info->start[0] + info->size)) ) { + return (info); + } + } + + return (NULL); +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + * Make sure all target addresses are within Flash bounds, + * and no protected sectors are hit. + * Returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - target range includes protected sectors + * 8 - target address not in Flash memory + */ +int +flash_write (uchar *src, ulong addr, ulong cnt) +{ + int i; + ulong end = addr + cnt - 1; + flash_info_t *info_first = addr2info (addr); + flash_info_t *info_last = addr2info (end ); + flash_info_t *info; + + if (cnt == 0) { + return (0); + } + + if (!info_first || !info_last) { + return (8); + } + + for (info = info_first; info <= info_last; ++info) { + ulong b_end = info->start[0] + info->size; /* bank end addr */ + short s_end = info->sector_count - 1; + for (i=0; isector_count; ++i) { + ulong e_addr = (i == s_end) ? b_end : info->start[i + 1]; + + if ((end >= info->start[i]) && (addr < e_addr) && + (info->protect[i] != 0) ) { + return (4); + } + } + } + + /* finally write data to flash */ + for (info = info_first; info <= info_last && cnt>0; ++info) { + ulong len; + + len = info->start[0] + info->size - addr; + if (len > cnt) + len = cnt; + if ((i = write_buff(info, src, addr, len)) != 0) { + return (i); + } + cnt -= len; + addr += len; + src += len; + } + return (0); +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - write error + */ + +static int +write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + ulong start, now, last; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + start = get_timer (0); + last = 0; + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + + /* show that we're waiting */ + now = get_timer(start); + if ((now - last) > 1000) { /* every second */ + serial_putc ('.'); + last = now; + } + } + + 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_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 3 - write error + */ +static int +write_word(flash_info_t *info, ulong dest, ulong data) +{ + flash_addr_t addr = (flash_addr_t)dest; + flash_word_t value = (flash_word_t)data, stat; + ulong start; + int flag, retval; + + /* Check if Flash is (sufficiently) erased */ + if ((*addr & value) != value) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + *addr = BANK_CMD_PROG; + + *addr = data; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + retval = 0; + + /* data polling for D7 */ + start = get_timer (0); + do { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + retval = 1; + goto done; + } + stat = *addr; + } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY); + + if ((stat & BANK_STAT_ERR) != 0) { + printf("flash program failed (stat = 0x%08lx) " + "at address 0x%08lx\n", stat, dest); + *addr = BANK_CMD_CLR_STAT; + retval = 3; + } + +done: + /* reset to read mode */ + *addr = BANK_CMD_RST; + + return (retval); +} + +/*----------------------------------------------------------------------- + */ diff --git a/cogent/cma302/kbd_mouse.c b/cogent/cma302/kbd_mouse.c new file mode 100644 index 0000000..fd7ea97 --- /dev/null +++ b/cogent/cma302/kbd_mouse.c @@ -0,0 +1 @@ +int cma302_kbd_mouse_not_implemented = 1; diff --git a/cogent/config.mk b/cogent/config.mk new file mode 100644 index 0000000..0f61b01 --- /dev/null +++ b/cogent/config.mk @@ -0,0 +1,42 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# Cogent Modular Architecture +# + +# select motherboard type and I/O modules present + +CMA_MB = cma10x +CMA_IOMS= cma302 # cmaNNN ... + +# configure the files to include from each directory + +cma10x_O= cma10x.o dipsw.o lcd.o serial.o # rtc.o parallel.o +cma302_O= flash.o # kbd_mouse.o +#cmaNNN_O=file.o file.o ... + +TEXT_BASE = 0xfff00000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) \ + $(foreach M,$(CMA_MB) $(CMA_IOMS),-I$(TOPDIR)/$(BOARD)/$M) diff --git a/cogent/ppcboot.lds b/cogent/ppcboot.lds new file mode 100644 index 0000000..989d8b5 --- /dev/null +++ b/cogent/ppcboot.lds @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* 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 : + { + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .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 = .); + + __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) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/cogent/ppcboot.lds.debug b/cogent/ppcboot.lds.debug new file mode 100644 index 0000000..4f2079a --- /dev/null +++ b/cogent/ppcboot.lds.debug @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* 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) + ppc/vsprintf.o (.text) + ppc/crc32.o (.text) + + . = env_offset; + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .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 = .); + + __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) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/common/Makefile b/common/Makefile index 184da55..2996c30 100644 --- a/common/Makefile +++ b/common/Makefile @@ -29,7 +29,7 @@ AOBJS = environment.o COBJS = board.o main.o command.o \ cmd_cache.o cmd_mem.o cmd_boot.o cmd_flash.o \ cmd_bootm.o cmd_net.o cmd_nvedit.o \ - s_record.o dlmalloc.o + s_record.o dlmalloc.o kgdb.o OBJS = $(AOBJS) $(COBJS) CPPFLAGS += -I.. diff --git a/common/board.c b/common/board.c index 72be1e7..f09a373 100644 --- a/common/board.c +++ b/common/board.c @@ -23,11 +23,12 @@ #include #include +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#include +#endif static char *failed = "*** failed ***\n"; -ulong cpu_speed; /* VCOOUT = CPU clock in Hz! */ - /* * Begin and End of memory area for malloc(), and current "brk" */ @@ -80,10 +81,13 @@ board_init_f (ulong bootflag) ulong dram_size; char *s, *e; int baudrate; + /* Pointer to initial global data area */ + init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); + /* CPU Clock Speed */ - cpu_speed = get_gclk_freq (); /* in Hz */ - clock_mhz = cpu_speed / 1000 / 1000; /* in MHz */ + idata->cpu_speed = get_gclk_freq (); /* in Hz */ + clock_mhz = idata->cpu_speed / 1000 / 1000; /* in MHz */ s = getenv ("baudrate"); baudrate = s ? (int)simple_strtoul(s, NULL, 10) : CONFIG_BAUDRATE; @@ -262,6 +266,11 @@ void board_init_r (bd_t *bd, ulong dest_addr) reset_phy (); #endif +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + printf (" KGDB: "); + kgdb_init(); +#endif + /* * Enable Interrupts */ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9120c28..9054ff3 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -107,8 +107,8 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) len_ptr = (ulong *)data; - if ((hdr->ih_os != IH_OS_LINUX) || (hdr->ih_arch != IH_CPU_PPC)) { - printf ("Unsupported OS or Architecture\n"); + if (hdr->ih_arch != IH_CPU_PPC) { + printf ("Unsupported Architecture\n"); return; } diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 774cd62..70fb0a0 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -40,6 +40,61 @@ void flash_sect_protect (int flag, ulong addr_first, ulong addr_last); * for historical reasons. */ +/* + * this routine looks for an abbreviated flash range specification. + * the syntax is B:SF[-SL], where B is the bank number, SF is the first + * sector to erase, and SL is the last sector to erase (defaults to SF). + * bank numbers start at 1 to be consistent with other specs, sector numbers + * start at zero. + * + * returns: 1 - correct spec; *pinfo, *psf and *psl are + * set appropriately + * 0 - doesn't look like an abbreviated spec + * -1 - looks like an abbreviated spec, but got + * a parsing error, a number out of range, + * or an invalid flash bank. + */ +static int +abbrev_spec(char *str, flash_info_t **pinfo, int *psf, int *psl) +{ + flash_info_t *fp; + int bank, first, last; + char *p, *ep; + + if ((p = strchr(str, ':')) == NULL) + return 0; + *p++ = '\0'; + + bank = simple_strtoul(str, &ep, 10); + if (ep == str || *ep != '\0' || + bank < 1 || bank > CFG_MAX_FLASH_BANKS || + (fp = &flash_info[bank - 1])->flash_id == FLASH_UNKNOWN) + return -1; + + str = p; + if ((p = strchr(str, '-')) != NULL) + *p++ = '\0'; + + first = simple_strtoul(str, &ep, 10); + if (ep == str || *ep != '\0' || first >= fp->sector_count) + return -1; + + if (p != NULL) { + last = simple_strtoul(p, &ep, 10); + if (ep == p || *ep != '\0' || + last < first || last >= fp->sector_count) + return -1; + } + else + last = first; + + *pinfo = fp; + *psf = first; + *psl = last; + + return 1; +} + void do_flinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong bank; @@ -67,6 +122,7 @@ void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { flash_info_t *info; ulong bank, addr_first, addr_last; + int n, sect_first, sect_last; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); @@ -82,6 +138,17 @@ void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) return; } + if ((n = abbrev_spec(argv[1], &info, §_first, §_last)) != 0) { + if (n < 0) { + printf("Bad sector specification\n"); + return; + } + printf ("Erase Flash Sectors %d-%d in Bank # %d ", + sect_first, sect_last, (info-flash_info)+1); + flash_erase(info, sect_first, sect_last); + return; + } + if (argc != 3) { printf ("Usage:\n%s\n", cmdtp->usage); return; @@ -108,6 +175,7 @@ void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) return; } + printf ("Erase Flash from 0x%08lx to 0x%08lx ", addr_first, addr_last); flash_sect_erase(addr_first, addr_last); } @@ -171,8 +239,7 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { flash_info_t *info; ulong bank, addr_first, addr_last; - int i; - int p; + int i, p, n, sect_first, sect_last; if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); @@ -200,6 +267,20 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) return; } + if ((n = abbrev_spec(argv[2], &info, §_first, §_last)) != 0) { + if (n < 0) { + printf("Bad sector specification\n"); + return; + } + printf("%sProtect Flash Sectors %d-%d in Bank # %d\n", + p ? "" : "Un-", sect_first, sect_last, + (info-flash_info)+1); + for (i = sect_first; i <= sect_last; i++) { + info->protect[i] = p; + } + return; + } + if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); return; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 6e667c4..48bb3bf 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -39,7 +39,8 @@ extern uchar environment[]; extern ulong env_size; -#if (CONFIG_COMMANDS & CFG_CMD_ENV) +/* need both ENV and flash */ +#if ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) static uchar *flash_addr = environment; #endif @@ -242,14 +243,20 @@ void do_setenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } } -#if (CONFIG_COMMANDS & CFG_CMD_ENV) +/* need both ENV and flash */ +#if ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int rc; extern void flash_sect_protect (int p, ulong addr_first, ulong addr_last); extern void flash_sect_erase (ulong addr_first, ulong addr_last); -#ifdef CONFIG_CPCI405 +#ifdef CONFIG_4xx + /* + * On ppc4xx still saved somewhere within a flash sector (no sector + * reserved for the environment variables). This will be changed in a + * future release. + */ ulong sector_flash_addr; ulong sector_flash_size; ulong sector_flash_offs; @@ -271,11 +278,6 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) sector_flash_size = info->start[i] - info->start[i-1]; sector_flash_offs = (ulong)flash_addr - info->start[i-1]; -#if 1 - printf("\nflash_addr = %08lx sector_addr=%08lx size=%08lx offs=%08lx\n", - (ulong)flash_addr, sector_flash_addr, sector_flash_size, sector_flash_offs); -#endif - /* * Copy sector down to ram */ @@ -334,7 +336,7 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif /* CONFIG_CPCI405 */ } -#endif /* CFG_CMD_ENV */ +#endif /* CFG_CMD_ENV + CFG_CMD_FLASH */ /* * s1 is either a simple 'name', or a 'name=value' pair. diff --git a/common/command.c b/common/command.c index 5054c51..289a5d4 100644 --- a/common/command.c +++ b/common/command.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include /* * HELP command @@ -141,6 +143,8 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_BDINFO CMD_TBL_FLINFO CMD_TBL_IMINFO + CMD_TBL_PCIINFO + CMD_TBL_IRQINFO CMD_TBL_FLERASE CMD_TBL_PROTECT CMD_TBL_LOOP @@ -148,6 +152,7 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_ICACHE CMD_TBL_DCACHE CMD_TBL_RESET + CMD_TBL_KGDB CMD_TBL_VERS CMD_TBL_HELP CMD_TBL_QUES diff --git a/common/kgdb.c b/common/kgdb.c new file mode 100644 index 0000000..3ae2fab --- /dev/null +++ b/common/kgdb.c @@ -0,0 +1,547 @@ +/* taken from arch/ppc/kernel/ppc-stub.c */ + +/**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or its performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +/**************************************************************************** + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ + * + * Description: low level support for gdb debugger. $ + * + * Considerations: only works on target hardware $ + * + * Written by: Glenn Engel $ + * ModuleState: Experimental $ + * + * NOTES: See Below $ + * + * Modified for SPARC by Stu Grossman, Cygnus Support. + * + * This code has been extensively tested on the Fujitsu SPARClite demo board. + * + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. + * + ************* + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * qOffsets Get section offsets. Reply is Text=xxx;Data=yyy;Bss=zzz + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * bBB..BB Set baud rate to BB..BB OK or BNN, then sets + * baud rate + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + ****************************************************************************/ + +#include + +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + +/* + * BUFMAX defines the maximum number of characters in inbound/outbound buffers + */ +#define BUFMAX 1024 +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; +static char remcomRegBuffer[BUFMAX]; + +static int initialized = 0; +static int kgdb_active = 0; +static u_int error_jmp_buf[BUFMAX/2]; +static int longjmp_on_fault = 0; +#ifdef KGDB_DEBUG +static int kdebug = 1; +#endif + +static const char hexchars[]="0123456789abcdef"; + +/* Convert ch from a hex digit to an int */ +static int +hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +/* Convert the memory pointed to by mem into hex, placing result in buf. + * Return a pointer to the last char put in buf (null). + */ +static unsigned char * +mem2hex(char *mem, char *buf, int count) +{ + unsigned char ch; + + longjmp_on_fault = 1; + while (count-- > 0) { + ch = *mem++; + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch & 0xf]; + } + *buf = 0; + longjmp_on_fault = 0; + return buf; +} + +/* convert the hex array pointed to by buf into binary to be placed in mem + * return a pointer to the character AFTER the last byte fetched from buf. +*/ +static char * +hex2mem(char *buf, char *mem, int count) +{ + int i, hexValue; + unsigned char ch; + char *mem_start = mem; + + longjmp_on_fault = 1; + for (i=0; i# */ +static void +getpacket(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + unsigned char ch; + + do { + /* wait around for the start character, ignore all other + * characters */ + while ((ch = (getDebugChar() & 0x7f)) != '$') { +#ifdef KGDB_DEBUG + serial_putc(ch); +#endif + ; + } + + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) { + ch = getDebugChar() & 0x7f; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + + if (count >= BUFMAX) + continue; + + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar() & 0x7f) << 4; + xmitcsum |= hex(getDebugChar() & 0x7f); + if (checksum != xmitcsum) + putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + /* if a sequence char is present, reply the ID */ + if (buffer[2] == ':') { + putDebugChar(buffer[0]); + putDebugChar(buffer[1]); + /* remove sequence chars from buffer */ + count = strlen(buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } while (checksum != xmitcsum); +} + +/* send the packet in buffer. */ +static void +putpacket(unsigned char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch, recv; + + /* $#. */ + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count])) { + putDebugChar(ch); + checksum += ch; + count += 1; + } + + putDebugChar('#'); + putDebugChar(hexchars[checksum >> 4]); + putDebugChar(hexchars[checksum & 0xf]); + recv = getDebugChar(); + } while ((recv & 0x7f) != '+'); +} + +/* + * This function does all command processing for interfacing to gdb. + */ +static int +handle_exception (struct pt_regs *regs) +{ + int addr; + int length; + char *ptr; + kgdb_data kd; + int i; + + if (!initialized) { + printf("kgdb: exception before kgdb is initialized! huh?\n"); + return (0); + } + + if (longjmp_on_fault) { + longjmp_on_fault = 0; + kgdb_longjmp((long*)error_jmp_buf, KGDBERR_MEMFAULT); + panic("kgdb longjump failed!\n"); + } + + if (kgdb_active) { + printf("kgdb: unexpected exception from within kgdb\n"); + return (0); + } + kgdb_active = 1; + + kgdb_interruptible(0); + + printf("kgdb: entering handle_exception; trap [0x%x]\n", + kgdb_trap(regs)); + + if (kgdb_setjmp((long*)error_jmp_buf) != 0) + panic("kgdb: error or fault in entry init!\n"); + + kgdb_enter(regs, &kd); + + ptr = remcomOutBuffer; + + *ptr++ = 'T'; + + *ptr++ = hexchars[kd.sigval >> 4]; + *ptr++ = hexchars[kd.sigval & 0xf]; + + for (i = 0; i < kd.nregs; i++) { + kgdb_reg *rp = &kd.regs[i]; + + *ptr++ = hexchars[rp->num >> 4]; + *ptr++ = hexchars[rp->num & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)&rp->val, ptr, 4); + *ptr++ = ';'; + } + + *ptr = 0; + +#ifdef KGDB_DEBUG + if (kdebug) + printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); +#endif + + putpacket(remcomOutBuffer); + + while (1) { + volatile int errnum; + + remcomOutBuffer[0] = 0; + + getpacket(remcomInBuffer); + + errnum = kgdb_setjmp((long*)error_jmp_buf); + + if (errnum == 0) switch (remcomInBuffer[0]) { + + case '?': /* report most recent signal */ + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[kd.sigval >> 4]; + remcomOutBuffer[2] = hexchars[kd.sigval & 0xf]; + remcomOutBuffer[3] = 0; + break; + +#ifdef KGDB_DEBUG + case 'd': + /* toggle debug flag */ + kdebug ^= 1; + break; +#endif + + case 'g': /* return the value of the CPU registers. */ + length = kgdb_getregs(regs, remcomRegBuffer, BUFMAX); + mem2hex(remcomRegBuffer, remcomOutBuffer, length); + break; + + case 'G': /* set the value of the CPU registers */ + length = strlen(&remcomInBuffer[1]); + if ((length & 1) != 0) kgdb_error(KGDBERR_BADPARAMS); + hex2mem(&remcomInBuffer[1], remcomRegBuffer, length); + kgdb_putregs(regs, remcomRegBuffer, length); + strcpy(remcomOutBuffer,"OK"); + break; + + case 'H': + /* don't do anything, yet, just acknowledge */ + if (hexToInt(&ptr, &addr)) + strcpy(remcomOutBuffer,"OK"); + else + kgdb_error(KGDBERR_BADPARAMS); + break; + + case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + /* Try to read %x,%x. */ + + ptr = &remcomInBuffer[1]; + + if (hexToInt(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length)) { + mem2hex((char *)addr, remcomOutBuffer, length); + } else { + kgdb_error(KGDBERR_BADPARAMS); + } + break; + + case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + /* Try to read '%x,%x:'. */ + + ptr = &remcomInBuffer[1]; + + if (hexToInt(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length) + && *ptr++ == ':') { + hex2mem(ptr, (char *)addr, length); + strcpy(remcomOutBuffer, "OK"); + } else { + kgdb_error(KGDBERR_BADPARAMS); + } + break; + + + case 'k': /* kill the program, actually just continue */ + kd.extype = KGDBEXIT_KILL; + goto doexit; + + case 'c': /* cAA..AA Continue; address AA..AA optional */ + /* try to read optional parameter, pc unchanged if no parm */ + kd.extype = KGDBEXIT_CONTINUE; + + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr, &addr)) { + kd.exaddr = addr; + kd.extype |= KGDBEXIT_WITHADDR; + } + + goto doexit; + + case 's': + kd.extype = KGDBEXIT_SINGLE; + + doexit: +/* Need to flush the instruction cache here, as we may have deposited a + * breakpoint, and the icache probably has no way of knowing that a data ref to + * some location may have changed something that is in the instruction cache. + */ + kgdb_flush_cache_all(); + kgdb_exit(regs, &kd); + kgdb_active = 0; + kgdb_interruptible(1); + return (1); + + case 'r': /* Reset (if user process..exit ???)*/ + panic("kgdb reset."); + break; + } /* switch */ + + if (errnum != 0) + sprintf(remcomOutBuffer, "E%02d", errnum); + +#ifdef KGDB_DEBUG + if (remcomOutBuffer[0] && kdebug) { + printf("kgdb: remcomInBuffer: %s\n", remcomInBuffer); + printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); + } +#endif + + /* reply to the request */ + putpacket(remcomOutBuffer); + + } /* while(1) */ +} + +/* + * kgdb_init must be called *after* the + * monitor is relocated into ram + */ +void +kgdb_init(void) +{ + + kgdb_serial_init(); + debugger_exception_handler = handle_exception; + initialized = 1; + + putDebugStr("kgdb ready\n"); + printf("[handler = 0x%08lx] ready\n", + (unsigned long)debugger_exception_handler); +} + +void +kgdb_error(int errnum) +{ + longjmp_on_fault = 0; + kgdb_longjmp((long*)error_jmp_buf, errnum); + panic("kgdb_error: longjmp failed!\n"); +} + +/* Output string in GDB O-packet format if GDB has connected. If nothing + output, returns 0 (caller must then handle output). */ +int +kgdb_output_string (const char* s, unsigned int count) +{ + char buffer[512]; + + count = (count <= (sizeof(buffer) / 2 - 2)) + ? count : (sizeof(buffer) / 2 - 2); + + buffer[0] = 'O'; + mem2hex ((char *)s, &buffer[1], count); + putpacket(buffer); + + return 1; +} + +void +breakpoint(void) +{ + if (!initialized) { + printf("breakpoint() called b4 kgdb init\n"); + return; + } + + kgdb_breakpoint(); +} + +void +do_kgdb(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + printf("Entering KGDB mode via exception handler...\n\n"); + breakpoint(); + printf("\nReturned from KGDB mode\n"); +} + +#else + +int kgdb_not_configured = 1; + +#endif /* CFG_CMD_KGDB */ diff --git a/cpci405/cpci405.c b/cpci405/cpci405.c index 3226c81..6d115cf 100644 --- a/cpci405/cpci405.c +++ b/cpci405/cpci405.c @@ -28,6 +28,8 @@ #define _NOT_USED_ 0xFFFFFFFF +void pci_init(void); + /* ------------------------------------------------------------------------- */ @@ -75,6 +77,11 @@ int checkboard (void) check_serial(); + /* + * Do pci plug-n-play configuration + */ + pci_init(); + return (l_type); } diff --git a/include/asm/sigcontext.h b/include/asm/sigcontext.h new file mode 100644 index 0000000..4bd66a7 --- /dev/null +++ b/include/asm/sigcontext.h @@ -0,0 +1,15 @@ +#ifndef _ASM_PPC_SIGCONTEXT_H +#define _ASM_PPC_SIGCONTEXT_H + +#include + + +struct sigcontext_struct { + unsigned long _unused[4]; + int signal; + unsigned long handler; + unsigned long oldmask; + struct pt_regs *regs; +}; + +#endif diff --git a/include/asm/signal.h b/include/asm/signal.h new file mode 100644 index 0000000..f5025a1 --- /dev/null +++ b/include/asm/signal.h @@ -0,0 +1,154 @@ +#ifndef _ASMPPC_SIGNAL_H +#define _ASMPPC_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX (_NSIG-1) + +/* + * SA_FLAGS values: + * + * SA_ONSTACK is not currently supported, but will allow sigaltstack(2). + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND +#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +#define SA_RESTORER 0x04000000 + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 +#ifdef __KERNEL__ + +/* + * These values of sa_flags are used only by the kernel as part of the + * irq handling routines. + * + * SA_INTERRUPT is also used by the irq handling routines. + * SA_SHIRQ is for shared interrupt support on PCI and EISA. + */ +#define SA_PROBE SA_ONESHOT +#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_SHIRQ 0x04000000 +#endif + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(int); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include + +#endif + +#endif diff --git a/include/cmd_flash.h b/include/cmd_flash.h index 048ccf1..a728a6f 100644 --- a/include/cmd_flash.h +++ b/include/cmd_flash.h @@ -40,6 +40,7 @@ "erase - erase FLASH memory\n", \ "start end\n" \ " - erase FLASH from addr 'start' to addr 'end'\n" \ + "erase N:SF[-SL]\n - erase sectors SF-SL in FLASH bank # N\n" \ "erase bank N\n - erase FLASH bank # N\n" \ "erase all\n - erase all FLASH banks\n" \ ), @@ -49,10 +50,14 @@ "protect - enable or disable FLASH write protection\n", \ "on start end\n" \ " - protect FLASH from addr 'start' to addr 'end'\n" \ + "protect on N:SF[-SL]\n" \ + " - protect sectors SF-SL in FLASH bank # N\n" \ "protect on bank N\n - protect FLASH bank # N\n" \ "protect on all\n - protect all FLASH banks\n" \ "protect off start end\n" \ " - make FLASH from addr 'start' to addr 'end' writable\n" \ + "protect off N:SF[-SL]\n" \ + " - make sectors SF-SL writable in FLASH bank # N\n" \ "protect off bank N\n - make FLASH bank # N writable\n" \ "protect off all\n - make all FLASH banks writable\n" \ ), diff --git a/include/cmd_kgdb.h b/include/cmd_kgdb.h new file mode 100644 index 0000000..9607ea2 --- /dev/null +++ b/include/cmd_kgdb.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2000 + * Murray Jensen and + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * KGDB support + */ +#ifndef _CMD_KGDB_H +#define _CMD_KGDB_H + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CMD_TBL_KGDB MK_CMD_TBL_ENTRY( \ + "kgdb", 4, CFG_MAXARGS, do_kgdb, \ + "kgdb - enter gdb remote debug mode\n", \ + "\n - executes a breakpoint so that kgdb mode is\n" \ + " entered via the exception handler. To return\n" \ + " to the monitor, the remote gdb debugger must\n" \ + " execute a \"continue\" command.\n" \ +), + +void do_kgdb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +#else +#define CMD_TBL_KGDB +#endif + +#endif /* _CMD_KGDB_H */ diff --git a/include/cmd_misc.h b/include/cmd_misc.h new file mode 100644 index 0000000..fd337fc --- /dev/null +++ b/include/cmd_misc.h @@ -0,0 +1,2 @@ +#define CMD_TBL_PCIINFO +#define CMD_TBL_IRQINFO diff --git a/include/cmd_nvedit.h b/include/cmd_nvedit.h index b41dc7f..4a12d79 100644 --- a/include/cmd_nvedit.h +++ b/include/cmd_nvedit.h @@ -46,7 +46,7 @@ void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); ), void do_setenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); -#if (CONFIG_COMMANDS & CFG_CMD_ENV) +#if ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) #define CMD_TBL_SAVEENV MK_CMD_TBL_ENTRY( \ "saveenv", 4, 1, do_saveenv, \ "saveenv - save environment variables to persistent storage\n", \ diff --git a/include/command.h b/include/command.h index 9f62b31..521b4ef 100644 --- a/include/command.h +++ b/include/command.h @@ -31,6 +31,7 @@ #define NULL 0 #endif +#ifndef __ASSEMBLY__ /* * Monitor Command Table */ @@ -71,6 +72,8 @@ extern cmd_tbl_t cmd_tbl[]; typedef void command_t (cmd_tbl_t *, bd_t *, int, int, char *[]); +#endif /* __ASSEMBLY__ */ + /* * Command Flags: */ @@ -89,11 +92,16 @@ typedef void command_t (cmd_tbl_t *, bd_t *, int, int, char *[]); /* crc, base, loop, mtest */ #define CFG_CMD_NET 0x00000080 /* bootp, tftpboot, rarpboot */ #define CFG_CMD_ENV 0x00000100 /* saveenv */ +#define CFG_CMD_KGDB 0x00000200 /* kgdb */ #define CFG_CMD_ALL 0xFFFFFFFF /* ALL commands */ +/* Default configuration: everything but KGDB (which is quite big) + */ +#define CONFIG_CMD_DFL (CFG_CMD_ALL & ~(CFG_CMD_KGDB)) + #ifndef CONFIG_COMMANDS -#define CONFIG_COMMANDS CFG_CMD_ALL +#define CONFIG_COMMANDS CONFIG_CMD_DFL #endif #endif /* __COMMAND_H */ diff --git a/include/commproc.h b/include/commproc.h index 1c949de..da6404a 100644 --- a/include/commproc.h +++ b/include/commproc.h @@ -389,6 +389,7 @@ typedef struct scc_enet { * clock pins. */ #define PROFF_ENET PROFF_SCC1 +#define CPM_CR_ENET CPM_CR_CH_SCC1 #define SCC_ENET 0 #define PA_ENET_RXD ((ushort)0x0001) #define PA_ENET_TXD ((ushort)0x0002) @@ -524,7 +525,7 @@ typedef struct scc_enet { */ #define SICR_ENET_MASK ((uint)0x0000ff00) #define SICR_ENET_CLKRT ((uint)0x00002600) -#endif /* CONFIG_TQM823L, CONFIG_TQM850L */ +#endif /* CONFIG_TQM823L, CONFIG_TQM850L, CONFIG_ETX094 */ /*** FPC850 *********************************************************/ @@ -551,9 +552,9 @@ typedef struct scc_enet { #define SICR_ENET_CLKRT ((uint)0x00002600) #endif /* CONFIG_FPS850L */ -/*** TQM860L ********************************************************/ +/*** TQM860L, TQM855L*************************************************/ -#ifdef CONFIG_TQM860L +#if (defined(CONFIG_TQM860L) || defined(CONFIG_TQM855L)) /* Bits in parallel I/O port registers that have to be set/cleared * to configure the pins for SCC1 use. */ @@ -574,7 +575,7 @@ typedef struct scc_enet { */ #define SICR_ENET_MASK ((uint)0x000000ff) #define SICR_ENET_CLKRT ((uint)0x00000026) -#endif /* CONFIG_TQM860L */ +#endif /* CONFIG_TQM860L, CONFIG_TQM855L */ /*** SPD823TS ******************************************************/ @@ -584,8 +585,7 @@ typedef struct scc_enet { */ #define PROFF_ENET PROFF_SCC2 /* Ethernet at SCC2 */ #define CPM_CR_ENET CPM_CR_CH_SCC2 -#define SCC_ENET 1 /* index in SCC table starts - with 0, so we have here 1 */ +#define SCC_ENET 1 #define PA_ENET_MDC ((ushort)0x0001) /* PA 15 !!! */ #define PA_ENET_MDIO ((ushort)0x0002) /* PA 14 !!! */ #define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ diff --git a/include/config_ADCIOP.h b/include/config_ADCIOP.h index 51890d7..31b3f96 100644 --- a/include/config_ADCIOP.h +++ b/include/config_ADCIOP.h @@ -52,23 +52,24 @@ "nfsaddrs=10.0.0.99:10.0.0.2" #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ -#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ - -#define CONFIG_LOADB 1 /* command loadb for binary (kermit) */ - /* image load included */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ #define CONFIG_DRAM_SPEED (CONFIG_BUSCLOCK) /* MHz */ -#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET) /* no network on ADCIOP */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) /* no network on ADCIOP */ /* * Miscellaneous configurable options */ -#define CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 8 /* max number of command args */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x0400000 /* memtest works on */ @@ -78,24 +79,33 @@ #define CFG_BAUDRATE_MAX 115200 /* highest possible baudrate */ #define CFG_BAUDRATE_DEFAULT CONFIG_BAUDRATE /* default baudrate */ -#define CFG_TFTP_LOADADDR 0x100000 /* default load address */ +#define CFG_TFTP_LOADADDR 0x100000 /* default load address */ + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR 0x00010000 /* external SDRAM */ +#define CFG_INIT_RAM_END 0x1000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) * Please note that CFG_SDRAM_BASE _must_ start at 0 */ -#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_BASE 0x00000000 #define CFG_FLASH_BASE 0xFFFE0000 -#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is * the maximum mapped by the Linux kernel during initialization. */ -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ /*----------------------------------------------------------------------- * FLASH organization */ @@ -105,8 +115,8 @@ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ -#define CFG_FLASH_ENV_OFFSET 0x8000 /* Offset of Environment Sector */ -#define CFG_FLASH_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ +#define CFG_FLASH_ENV_OFFSET 0x8000 /* Offset of Environment Sector */ +#define CFG_FLASH_ENV_SIZE 0x2000 /* Total Size of Environment Sector */ /*----------------------------------------------------------------------- * Cache Configuration @@ -128,7 +138,7 @@ * * Boot Flags */ -#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ #endif /* __CONFIG_H */ diff --git a/include/config_CPCI405.h b/include/config_CPCI405.h index 7edfed7..0793d8f 100644 --- a/include/config_CPCI405.h +++ b/include/config_CPCI405.h @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -33,13 +33,13 @@ * (easy to change) */ -#define CONFIG_PPC405GP 1 /* This is a PPC405 CPU */ -#define CONFIG_CPCI405 1 /* ...on a CPCI405 board */ +#define CONFIG_PPC405GP 1 /* This is a PPC405 CPU */ +#define CONFIG_CPCI405 1 /* ...on a CPCI405 board */ -#define CONFIG_CPUCLOCK 200 -#define CONFIG_BUSCLOCK 100 +#define CONFIG_CPUCLOCK 200 +#define CONFIG_BUSCLOCK 100 -#define CONFIG_BAUDRATE 9600 +#define CONFIG_BAUDRATE 9600 #if 0 #define CONFIG_BOOTDELAY -1 /* autoboot disabled */ #else @@ -49,7 +49,7 @@ #if 1 #define CONFIG_BOOTCOMMAND "bootm ffc00000" /* autoboot command */ #else -#define CONFIG_BOOTCOMMAND "net" /* autoboot command */ +#define CONFIG_BOOTCOMMAND "bootp" /* autoboot command */ #endif #if 0 @@ -57,80 +57,76 @@ "nfsroot=10.0.0.2:/LinuxPPC " \ "nfsaddrs=10.0.0.99:10.0.0.2" #else -#if 0 -#define CONFIG_BOOTARGS " root=/dev/hda1" \ - " ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0:ftest4:eth0:off" \ - " hda=bswap" -#else -#define CONFIG_BOOTARGS " root=/dev/hda1" \ - " ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0:" \ - " hda=bswap" -#endif +#define CONFIG_BOOTARGS "root=/dev/hda1 " \ + "ip=192.168.2.176:192.168.2.190:192.168.2.79:255.255.255.0: " \ + "hda=bswap" + #endif #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ -#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ - -#define CONFIG_LOADB 1 /* command loadb for binary (kermit) */ - /* image load included */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ -#define CONFIG_PCI_PNP 1 /* include pci plug-and-play */ -#define CONFIG_PCIINFO 1 /* include pci info command */ +#define CONFIG_PCI_PNP 1 /* include pci plug-and-play */ +#define CONFIG_PCIINFO 1 /* include pci info command */ -#define CONFIG_IRQINFO 1 /* include irq info command */ +#define CONFIG_IRQINFO 1 /* include irq info command */ #define CONFIG_DRAM_SPEED (CONFIG_BUSCLOCK) /* MHz */ /* * Miscellaneous configurable options */ -#define CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 8 /* max number of command args */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x0400000 /* memtest works on */ #define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ -#define CFG_BAUDRATE_MIN 300 /* lowest possible baudrate */ -#define CFG_BAUDRATE_MAX 115200 /* highest possible baudrate */ -#define CFG_BAUDRATE_DEFAULT CONFIG_BAUDRATE /* default baudrate */ +#define CFG_BAUDRATE_MIN 300 /* lowest possible baudrate */ +#define CFG_BAUDRATE_MAX 115200 /* highest possible baudrate */ +#define CFG_BAUDRATE_DEFAULT CONFIG_BAUDRATE /* default baudrate */ -#define CFG_TFTP_LOADADDR 0x100000 /* default load address */ +#define CFG_TFTP_LOADADDR 0x100000 /* default load address */ /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) * Please note that CFG_SDRAM_BASE _must_ start at 0 */ -#define CFG_SDRAM_BASE 0x00000000 +#define CFG_SDRAM_BASE 0x00000000 #if 1 #define CFG_FLASH_BASE 0xFFFE0000 #else #define CFG_FLASH_BASE 0x00FE0000 #endif -#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ -#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ +#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is * the maximum mapped by the Linux kernel during initialization. */ -#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ /*----------------------------------------------------------------------- * FLASH organization */ #define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ -#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ +#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ -#define CFG_FLASH_ENV_OFFSET 0x9000 /* Offset of Environment Sector */ -#define CFG_FLASH_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +#define CFG_FLASH_ENV_OFFSET 0x9000 /* Offset of Environment Sector */ +#define CFG_FLASH_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ /*----------------------------------------------------------------------- * Cache Configuration @@ -148,10 +144,19 @@ /* On Chip Memory location */ -#define OCM_DATA_ADDR 0xF8000000 +#define OCM_DATA_ADDR 0xF8000000 /* Configuration Port location */ -#define CONFIG_PORT_ADDR 0xF0000500 +#define CONFIG_PORT_ADDR 0xF0000500 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR OCM_DATA_ADDR /* On Chip SRAM (4K) */ +#define CFG_INIT_RAM_END 0x0f00 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET /* @@ -159,7 +164,7 @@ * * Boot Flags */ -#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ #endif /* __CONFIG_H */ diff --git a/include/config_ETX094.h b/include/config_ETX094.h index 8948ef8..07c4c2b 100644 --- a/include/config_ETX094.h +++ b/include/config_ETX094.h @@ -58,7 +58,11 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -78,6 +82,15 @@ */ #define CFG_IMMR 0xFFF00000 +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) @@ -185,13 +198,6 @@ /*#define CFG_DER 0x2002000F*/ #define CFG_DER 0 -#define MPC8XX_FACT 1 /* Multiply by 1 */ -#if 0 -#define MPC8XX_XIN 50000000 /* 50 MHz in - ??? - XXX */ -/* #define MPC8XX_BUSDIV 2 */ -#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT)) -#endif - /* * Init Memory Controller: * diff --git a/include/config_FADS850SAR.h b/include/config_FADS850SAR.h index 6748340..6c5dcb6 100644 --- a/include/config_FADS850SAR.h +++ b/include/config_FADS850SAR.h @@ -68,7 +68,11 @@ */ #undef CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT ":>" /* Monitor Command Prompt */ -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -77,6 +81,7 @@ #define CFG_MEMTEST_END 0x00800000 /* 4 ... 8 MB in DRAM */ #define CFG_TFTP_LOADADDR 0x00100000 /* default load address */ + /* * Low Level Configuration Settings * (address mappings, register initial values, etc.) @@ -88,6 +93,15 @@ #define CFG_IMMR 0xFF000000 #define CFG_IMMR_SIZE ((uint)(64 * 1024)) +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) diff --git a/include/config_FADS860T.h b/include/config_FADS860T.h index b29724c..7a3d685 100644 --- a/include/config_FADS860T.h +++ b/include/config_FADS860T.h @@ -65,14 +65,18 @@ #define CONFIG_BOOTCOMMAND "bootm 2800100" /* autoboot command */ #define CONFIG_BOOTARGS " " -#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET) /* no network yet ??? */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET) /* no network yet ??? */ /* * Miscellaneous configurable options */ #undef CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT ":>" /* Monitor Command Prompt */ -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -94,6 +98,15 @@ #define CFG_IMMR 0xFF000000 #define CFG_IMMR_SIZE ((uint)(64 * 1024)) +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) diff --git a/include/config_SPD823TS.h b/include/config_SPD823TS.h index 687174b..08e4dec 100644 --- a/include/config_SPD823TS.h +++ b/include/config_SPD823TS.h @@ -53,6 +53,8 @@ #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */ +#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~(CFG_CMD_FLASH)) /* no Flash */ + /*----------------------------------------------------------------------*/ #define CONFIG_ETHADDR 00:d0:93:00:01:cb #define CONFIG_IPADDR 10.0.0.98 @@ -64,7 +66,11 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -84,6 +90,15 @@ */ #define CFG_IMMR 0xFFF00000 /* was: 0xFF000000 */ +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) @@ -157,11 +172,12 @@ * interrupt status bit, set PLL multiplication factor ! */ /* 0x00b0c0c0 */ -#define CFG_PLPRCR \ - 11 << (PLPRCR_MF_SHIFT) | \ - (PLPRCR_SPLSS | PLPRCR_TEXPS| /*PLPRCR_TMIST|*/ \ - /*PLPRCR_CSRC|*/ PLPRCR_LPM_NORMAL| \ - PLPRCR_CSR|PLPRCR_LOLRE/*|PLPRCR_FIOPD*/) +#define CFG_PLPRCR \ + ( (11 << PLPRCR_MF_SHIFT) | \ + PLPRCR_SPLSS | PLPRCR_TEXPS | /*PLPRCR_TMIST|*/ \ + /*PLPRCR_CSRC|*/ PLPRCR_LPM_NORMAL | \ + PLPRCR_CSR | PLPRCR_LOLRE /*|PLPRCR_FIOPD*/ \ + ) /*----------------------------------------------------------------------- * SCCR - System Clock and reset Control Register 15-27 @@ -241,13 +257,6 @@ /*#define CFG_DER 0x2002000F*/ #define CFG_DER 0 -#define MPC8XX_FACT 1 /* Multiply by 1 */ -#if 0 -#define MPC8XX_XIN 50000000 /* 50 MHz in - ??? - XXX */ -/* #define MPC8XX_BUSDIV 2 */ -#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT)) -#endif - /* * Init Memory Controller: * diff --git a/include/config_TQM823L.h b/include/config_TQM823L.h index 34517f6..b18caf2 100644 --- a/include/config_TQM823L.h +++ b/include/config_TQM823L.h @@ -58,7 +58,11 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -78,6 +82,15 @@ */ #define CFG_IMMR 0xFFF00000 +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) @@ -185,13 +198,6 @@ /*#define CFG_DER 0x2002000F*/ #define CFG_DER 0 -#define MPC8XX_FACT 1 /* Multiply by 1 */ -#if 0 -#define MPC8XX_XIN 50000000 /* 50 MHz in - ??? - XXX */ -/* #define MPC8XX_BUSDIV 2 */ -#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT)) -#endif - /* * Init Memory Controller: * diff --git a/include/config_TQM850L.h b/include/config_TQM850L.h index 8f0a25c..39b9505 100644 --- a/include/config_TQM850L.h +++ b/include/config_TQM850L.h @@ -58,7 +58,11 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -78,6 +82,15 @@ */ #define CFG_IMMR 0xFFF00000 +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) @@ -185,13 +198,6 @@ /*#define CFG_DER 0x2002000F*/ #define CFG_DER 0 -#define MPC8XX_FACT 1 /* Multiply by 1 */ -#if 0 -#define MPC8XX_XIN 50000000 /* 50 MHz in - ??? - XXX */ -/* #define MPC8XX_BUSDIV 2 */ -#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT)) -#endif - /* * Init Memory Controller: * diff --git a/include/config_TQM855L.h b/include/config_TQM855L.h new file mode 100644 index 0000000..2077188 --- /dev/null +++ b/include/config_TQM855L.h @@ -0,0 +1,299 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define TQM8xxL_80MHz 1 /* define for 80 MHz CPU only */ + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC855 1 /* This is a MPC855 CPU */ +#define CONFIG_TQM855L 1 /* ...on a TQM8xxL module */ + +#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */ +#undef CONFIG_8xx_CONS_SMC2 +#define CONFIG_BAUDRATE 115200 /* console baudrate = 115kbps */ +#if 0 +#define CONFIG_BOOTDELAY -1 /* autoboot disabled */ +#else +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#endif +#define CONFIG_BOOTCOMMAND "bootm 40020000" /* autoboot command */ + +#define CONFIG_BOOTARGS "root=/dev/nfs rw " \ + "nfsroot=10.0.0.2:/LinuxPPC " \ + "nfsaddrs=10.0.0.99:10.0.0.2" + +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 8 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ + +#define CFG_TFTP_LOADADDR 0x100000 /* default load address */ + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ +/*----------------------------------------------------------------------- + * Internal Memory Mapped Register + */ +#define CFG_IMMR 0xFFF00000 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_FLASH_BASE 0x40000000 +#ifdef DEBUG +#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ +#else +#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#endif +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#define CFG_FLASH_ENV_OFFSET 0x8000 /* Offset of Environment Sector */ +#define CFG_FLASH_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */ + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze + */ +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP) + +/*----------------------------------------------------------------------- + * SUMCR - SIU Module Configuration 11-6 + *----------------------------------------------------------------------- + * PCMCIA config., multi-function pin tri-state + */ +#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01) + +/*----------------------------------------------------------------------- + * TBSCR - Time Base Status and Control 11-26 + *----------------------------------------------------------------------- + * Clear Reference Interrupt Status, Timebase freezing enabled + */ +#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 11-31 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled + */ +#define CFG_PISCR (PISCR_PS | PISCR_PITF) + +/*----------------------------------------------------------------------- + * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30 + *----------------------------------------------------------------------- + * Reset PLL lock status sticky bit, timer expired status bit and timer + * interrupt status bit + * + * This is a 80 MHz CPU, so set PLL multiplication factor to 5 (5*16=80)! + */ +#ifdef TQM8xxL_80MHz /* for 80 MHz, we use a 16 MHz clock * 5 */ +#define CFG_PLPRCR \ + ( (5-1)< " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else #define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ #define CFG_MAXARGS 8 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ @@ -78,6 +82,15 @@ */ #define CFG_IMMR 0xFFF00000 +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + /*----------------------------------------------------------------------- * Start addresses for the final memory configuration * (Set up by the startup code) @@ -185,13 +198,6 @@ /*#define CFG_DER 0x2002000F*/ #define CFG_DER 0 -#define MPC8XX_FACT 1 /* Multiply by 1 */ -#if 0 -#define MPC8XX_XIN 50000000 /* 50 MHz in - ??? - XXX */ -/* #define MPC8XX_BUSDIV 2 */ -#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT)) -#endif - /* * Init Memory Controller: * diff --git a/include/config_cogent_mpc8xx.h b/include/config_cogent_mpc8xx.h new file mode 100644 index 0000000..4e0bab4 --- /dev/null +++ b/include/config_cogent_mpc8xx.h @@ -0,0 +1,328 @@ +/* + * (C) Copyright 2000 + * Murray Jensen + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Config header file for Cogent platform using an MPC8xx CPU module + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC860 1 /* This is a MPC860 CPU */ +#define CONFIG_COGENT 1 /* using Cogent Modular Architecture */ + +/* Cogent Modular Architecture options */ +#define CONFIG_CMA286_60_OLD 1 /* ...on an old CMA286-60 CPU module */ +#define CONFIG_CMA102 1 /* ...on a CMA102 motherboard */ +#define CONFIG_CMA302 1 /* ...with a CMA302 flash I/O module */ + +/* Cogent sanity checking */ +#if defined(CONFIG_COGENT) + +/* check a cpu module has been selected */ +# if defined(CONFIG_CMA286_21) +# define COGENT_CPU_MODULE "CMA286-21" +# elif defined(CONFIG_CMA286_60_OLD) +# define COGENT_CPU_MODULE "CMA286-60 (old)" +# elif defined(CONFIG_CMA286_60) +# define COGENT_CPU_MODULE "CMA286-60" +# elif defined(CONFIG_CMA286_60P) +# define COGENT_CPU_MODULE "CMA286-60P" +# elif defined(CONFIG_CMA287_21) +# define COGENT_CPU_MODULE "CMA287-21" +# elif defined(CONFIG_CMA287_50) +# define COGENT_CPU_MODULE "CMA287-50" +# else +# error Cogent CPU Module either unsupported or undefined +# endif + +/* check a motherboard has been selected */ +# if defined(CONFIG_CMA101) +# define COGENT_MOTHERBOARD "CMA101" +# elif defined(CONFIG_CMA102) +# define COGENT_MOTHERBOARD "CMA102" +# else +# error Cogent Motherboard either unsupported or undefined +# endif + +/* check a flash i/o module has been selected */ +# if defined(CONFIG_CMA302) +# define COGENT_FLASH_MODULE "CMA302" +# else +# error Cogent Flash I/O module either unsupported or undefined +# endif + +#endif + +#if defined(CONFIG_CMA101) || defined(CONFIG_CMA102) +#define CONFIG_LCD_HEARTBEAT +#endif + +#if defined(CONFIG_CMA286_60_OLD) +#define CONFIG_8xx_GCLK_FREQ 33333000/* define if cant use get_gclk_freq */ +#endif +#define CONFIG_8xx_WATCHDOG /* enables watchdog in 8xx SIU */ +#undef CONFIG_8xx_CONS_SMC1 +#undef CONFIG_8xx_CONS_SMC2 +#define CONFIG_8xx_CONS_NONE 1 /* Console is on the m/b serial */ + +#define CONFIG_BAUDRATE 230400 +#if 0 +#define CONFIG_BOOTDELAY -1 /* autoboot disabled */ +#else +#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ +#endif +#define CONFIG_BOOTCOMMAND "bootm 04080000 04200000" /* autoboot command*/ + +#define CONFIG_BOOTARGS "root=/dev/ram rw" + +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) && defined(KGDB_DEBUG) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 8 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x00400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x01c00000 /* 4 ... 28 MB in DRAM */ +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ +/*----------------------------------------------------------------------- + * Internal Memory Mapped Register + */ +#define CFG_IMMR 0xFF000000 + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in DPRAM) + */ +#define CFG_INIT_RAM_ADDR CFG_IMMR +#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE CFG_CMA_CS1_BASE +#define CFG_FLASH_BASE CFG_CMA_CS2_BASE +#if defined(CONFIG_CMA101) || defined(CONFIG_CMA102) +#define CFG_MBIO_BASE CFG_CMA_CS3_BASE +#endif +#define CFG_MONITOR_BASE TEXT_BASE +#define CFG_MONITOR_LEN (128 << 10) /* Reserve 128 kB for Monitor */ +#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 67 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +#define CFG_FLASH_ENV_ADDR CFG_FLASH_BASE /* Addr of Environment Sector */ +#define CFG_FLASH_ENV_SIZE 0x1000 /* Total Size of Environment Sector */ +#define CFG_FLASH_ENV_BUF (512*1024) /* see README - env sect real size */ +#define CFG_ENV_MAGIC 0xA4 /* indicates environment valid */ +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */ + +/*----------------------------------------------------------------------- + * SYPCR - System Protection Control 11-9 + * SYPCR can only be written once after reset! + *----------------------------------------------------------------------- + * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze + */ +#if defined(CONFIG_8xx_WATCHDOG) +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWE | SYPCR_SWP) +#else +#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | SYPCR_SWP) +#endif + +/*----------------------------------------------------------------------- + * SUMCR - SIU Module Configuration 11-6 + *----------------------------------------------------------------------- + * PCMCIA config., multi-function pin tri-state + */ +#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01) + +/*----------------------------------------------------------------------- + * TBSCR - Time Base Status and Control 11-26 + *----------------------------------------------------------------------- + * Clear Reference Interrupt Status, Timebase freezing enabled + */ +#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF) + +/*----------------------------------------------------------------------- + * PISCR - Periodic Interrupt Status and Control 11-31 + *----------------------------------------------------------------------- + * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled + */ +#define CFG_PISCR (PISCR_PS | PISCR_PITF) + +/*----------------------------------------------------------------------- + * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30 + *----------------------------------------------------------------------- + * Reset PLL lock status sticky bit, timer expired status bit and timer + * interrupt status bit - leave PLL multiplication factor unchanged ! + */ +#define CFG_PLPRCR (PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST) + +/*----------------------------------------------------------------------- + * SCCR - System Clock and reset Control Register 15-27 + *----------------------------------------------------------------------- + * Set clock output, timebase and RTC source and divider, + * power management and some other internal clocks + */ +#define SCCR_MASK SCCR_EBDF11 +#define CFG_SCCR (SCCR_TBS | SCCR_RTDIV | SCCR_RTSEL | \ + SCCR_COM00 | SCCR_DFSYNC00 | SCCR_DFBRG00 | \ + SCCR_DFNL000 | SCCR_DFNH000 | SCCR_DFLCD000 | \ + SCCR_DFALCD00) + +/*----------------------------------------------------------------------- + * PCMCIA stuff + *----------------------------------------------------------------------- + * + */ +#define CFG_PCMCIA_MEM_ADDR (0xE0000000) +#define CFG_PCMCIA_MEM_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_DMA_ADDR (0xE4000000) +#define CFG_PCMCIA_DMA_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_ATTRB_ADDR (0xE8000000) +#define CFG_PCMCIA_ATTRB_SIZE ( 64 << 20 ) +#define CFG_PCMCIA_IO_ADDR (0xEC000000) +#define CFG_PCMCIA_IO_SIZE ( 64 << 20 ) + +/*----------------------------------------------------------------------- + * + *----------------------------------------------------------------------- + * + */ +/*#define CFG_DER 0x2002000F*/ +#define CFG_DER 0 + +#if defined(CONFIG_CMA286_60_OLD) + +/* + * Init Memory Controller: + * + * NOTE: although the names (CFG_xRn_PRELIM) suggest preliminary settings, + * they are actually the final settings for this cpu/board, because the + * flash and RAM are on the motherboard, accessed via the CMAbus, and the + * mappings are pretty much fixed. + */ + +#define CFG_CMA_CS0_BASE TEXT_BASE /* EPROM */ +#define CFG_CMA_CS0_SIZE (1 << 20) +#define CFG_CMA_CS1_BASE 0x00000000 /* M/B RAM + I/O SLOT 1 */ +#define CFG_CMA_CS1_SIZE (64 << 20) +#define CFG_CMA_CS2_BASE 0x04000000 /* I/O SLOTS 2 + 3 */ +#define CFG_CMA_CS2_SIZE (64 << 20) +#define CFG_CMA_CS3_BASE 0x0e000000 /* M/B I/O */ +#define CFG_CMA_CS3_SIZE (32 << 20) + +/* + * CS0 enables the EPROM on the cpu module + * Set it for 4 wait states, address CFG_MONITOR_BASE and size 1M + * + * Note: We must have already transferred control to the high addresses + * before coming here, because the next two statements will make the + * mirror of the eprom at address 0 disappear. + */ + +/* base address = CFG_CMA_CS0_BASE, 16-bit, no parity, r/o, gpcm */ +#define CFG_BR0_PRELIM ((CFG_CMA_CS0_BASE&BR_BA_MSK)|BR_PS_16|BR_WP|BR_V) +/* mask size CFG_CMA_CS0_SIZE, CS time normal, burst inhibit, 4-wait states */ +#define CFG_OR0_PRELIM ((~(CFG_CMA_CS0_SIZE-1)&OR_AM_MSK)|OR_BI|OR_SCY_4_CLK) + +/* + * CS1 enables motherboard DRAM and motherboard I/O slot 1 + * (each 32Mbyte in size) + */ + +/* base address = CFG_CMA_CS1_BASE, 32-bit, no parity, r/w, gpcm */ +#define CFG_BR1_PRELIM ((CFG_CMA_CS1_BASE&BR_BA_MSK)|BR_V) +/* mask size CFG_CMA_CS1_SIZE, CS time normal, burst ok, ext xfer ack */ +#define CFG_OR1_PRELIM ((~(CFG_CMA_CS1_SIZE-1)&OR_AM_MSK)|OR_SETA) + +/* + * CS2 enables motherboard I/O slots 2 and 3 + * (each 32Mbyte in size) + */ + +/* base address = CFG_CMA_CS2_BASE, 32-bit, no parity, r/w, gpcm */ +#define CFG_BR2_PRELIM ((CFG_CMA_CS2_BASE&BR_BA_MSK)|BR_V) +/* mask size CFG_CMA_CS2_SIZE, CS time normal, burst ok, ext xfer ack */ +#define CFG_OR2_PRELIM ((~(CFG_CMA_CS2_SIZE-1)&OR_AM_MSK)|OR_SETA) + +/* + * CS3 enables motherboard I/O + * (32Mbyte in size) + */ + +/* base address = CFG_CMA_CS3_BASE, 32-bit, no parity, r/w, gpcm */ +#define CFG_BR3_PRELIM ((CFG_CMA_CS3_BASE&BR_BA_MSK)|BR_V) +/* mask size CFG_CMA_CS3_SIZE, CS time normal, burst inhibit, ext xfer ack */ +#define CFG_OR3_PRELIM ((~(CFG_CMA_CS3_SIZE-1)&OR_AM_MSK)|OR_BI|OR_SETA) + +#endif + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ diff --git a/include/kgdb.h b/include/kgdb.h new file mode 100644 index 0000000..93f60bd --- /dev/null +++ b/include/kgdb.h @@ -0,0 +1,68 @@ +#ifndef __KGDB_H__ +#define __KGDB_H__ + +#include + +#define KGDBERR_BADPARAMS 1 +#define KGDBERR_NOTHEXDIG 2 +#define KGDBERR_MEMFAULT 3 +#define KGDBERR_NOSPACE 4 + +#define KGDBDATA_MAXREGS 8 +#define KGDBDATA_MAXPRIV 8 + +#define KGDBEXIT_TYPEMASK 0xff + +#define KGDBEXIT_KILL 0 +#define KGDBEXIT_CONTINUE 1 +#define KGDBEXIT_SINGLE 2 + +#define KGDBEXIT_WITHADDR 0x100 + +typedef + struct { + int num; + unsigned long val; + } +kgdb_reg; + +typedef + struct { + int sigval; + int extype; + unsigned long exaddr; + int nregs; + kgdb_reg regs[KGDBDATA_MAXREGS]; + unsigned long private[KGDBDATA_MAXPRIV]; + } +kgdb_data; + +/* these functions are provided by the generic kgdb support */ +extern void kgdb_init(void); +extern void kgdb_error(int); +extern int kgdb_output_string(const char *, unsigned int); +extern void breakpoint(void); + +/* these functions are provided by the platform specific kgdb support */ +extern void kgdb_flush_cache_range(void *, void *); +extern void kgdb_flush_cache_all(void); +extern int kgdb_setjmp(long *); +extern void kgdb_longjmp(long *, int); +extern void kgdb_enter(struct pt_regs *, kgdb_data *); +extern void kgdb_exit(struct pt_regs *, kgdb_data *); +extern int kgdb_getregs(struct pt_regs *, char *, int); +extern void kgdb_putregs(struct pt_regs *, char *, int); +extern int kgdb_trap(struct pt_regs *); +extern void kgdb_breakpoint(void); + +/* these functions are provided by the platform serial driver */ +extern void kgdb_serial_init(void); +extern int getDebugChar(void); +extern void putDebugChar(int); +extern void putDebugStr(const char *); +extern void kgdb_interruptible(int); + +/* this is referenced in the trap handler for the platform */ +extern int (*debugger_exception_handler)(struct pt_regs *); + +#endif /* __KGDB_H__ */ diff --git a/include/ppcboot.h b/include/ppcboot.h index 55d89e7..c972f81 100644 --- a/include/ppcboot.h +++ b/include/ppcboot.h @@ -87,6 +87,17 @@ typedef struct bd_info { intr_util_t bi_interrupt; /* Addr of monitor fnc for Interrupts */ } bd_t; +/* The following data structure is placed in DPRAM to allow for a + * minimum set of global variables during system initialization + * (until we have set up the memory controller so that we can use + * RAM). + * + * Keep it *SMALL*! + */ +typedef struct init_data { + unsigned long cpu_speed; /* VCOOUT = CPU clock in Hz! */ +} init_data_t; + /* * Function Prototypes */ diff --git a/include/version.h b/include/version.h index cc43ba8..aa90ed7 100644 --- a/include/version.h +++ b/include/version.h @@ -24,6 +24,6 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define PPCBOOT_VERSION "ppcboot 0.5.1" +#define PPCBOOT_VERSION "ppcboot 0.5.2" #endif /* __VERSION_H__ */ diff --git a/mpc8xx/Makefile b/mpc8xx/Makefile index 67093fe..cf13d78 100644 --- a/mpc8xx/Makefile +++ b/mpc8xx/Makefile @@ -25,13 +25,14 @@ include $(TOPDIR)/config.mk LIB = lib$(CPU).a -START = start.o -OBJS = traps.o serial.o cpu.o cpu_init.o speed.o interrupts.o scc.o +START = start.o kgdb.o +OBJS = traps.o serial.o cpu.o cpu_init.o speed.o \ + interrupts.o scc.o all: .depend $(START) $(LIB) $(LIB): $(OBJS) - $(AR) crv $@ $(OBJS) + $(AR) crv $@ $(OBJS) kgdb.o ######################################################################### diff --git a/mpc8xx/cpu.c b/mpc8xx/cpu.c index eeb8620..71fa017 100644 --- a/mpc8xx/cpu.c +++ b/mpc8xx/cpu.c @@ -38,7 +38,12 @@ #include #include -#if defined(CONFIG_MPC860) +#if (defined(CONFIG_MPC860) || defined(CONFIG_MPC855)) +# ifdef CONFIG_MPC855 +# define ID_STR "PC855" +# else +# define ID_STR "PC860" +# endif static int check_CPU(long clock, uint pvr, uint immr) { @@ -54,28 +59,28 @@ static int check_CPU(long clock, uint pvr, uint immr) m = 0; switch(k) { - case 0x00020001 : printf("pPC860xxZPnn"); break; - case 0x00030001 : printf("XPC860xxZPnn"); break; + case 0x00020001 : printf("p" ID_STR "xxZPnn"); break; + case 0x00030001 : printf("X" ID_STR "xxZPnn"); break; - case 0x00120003 : printf("XPC860xxZPnnA"); break; - case 0x00130003 : printf("XPC860xxZPnnA3"); break; + case 0x00120003 : printf("X" ID_STR "xxZPnnA"); break; + case 0x00130003 : printf("X" ID_STR "xxZPnnA3"); break; - case 0x00200004 : printf("XPC860xxZPnnB"); break; + case 0x00200004 : printf("X" ID_STR "xxZPnnB"); break; - case 0x00300004 : printf("XPC860xxZPnnC"); break; - case 0x00310004 : printf("XPC860xxZPnnC1"); m = 1; break; + case 0x00300004 : printf("X" ID_STR "xxZPnnC"); break; + case 0x00310004 : printf("X" ID_STR "xxZPnnC1"); m = 1; break; - case 0x00200064 : printf("XPC860SRZPnnB"); break; - case 0x00300065 : printf("XPC860SRZPnnC"); break; - case 0x00310065 : printf("XPC860SRZPnnC1"); m = 1; break; - case 0x05010000 : printf("XPC860xxZPnnD3"); m = 1; break; + case 0x00200064 : printf("X" ID_STR "SRZPnnB"); break; + case 0x00300065 : printf("X" ID_STR "SRZPnnC"); break; + case 0x00310065 : printf("X" ID_STR "SRZPnnC1"); m = 1; break; + case 0x05010000 : printf("X" ID_STR "xxZPnnD3"); m = 1; break; /* this value is not documented anywhere */ - case 0x40000000 : printf("PPC860PZPnnD"); m = 1; break; + case 0x40000000 : printf("P" ID_STR "PZPnnD"); m = 1; break; - default: printf("unknown MPC860 (0x%08x)", k); + default: printf("unknown M" ID_STR " (0x%08x)", k); } printf(" at %lu MHz:", clock); @@ -335,14 +340,15 @@ void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) */ void udelay(unsigned long usec) { - extern ulong cpu_speed; ulong tbclk; ulong ticks; + /* Pointer to initial global data area */ + init_data_t *idata=(init_data_t *)(CFG_INIT_RAM_ADDR+CFG_INIT_DATA_OFFSET); if (((volatile immap_t *)CFG_IMMR)->im_clkrst.car_sccr & SCCR_TBS) { - tbclk = cpu_speed / 16; + tbclk = idata->cpu_speed / 16; } else { - ulong oscclk = cpu_speed / + ulong oscclk = idata->cpu_speed / ((((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT)+1); tbclk = oscclk / 4; } diff --git a/mpc8xx/cpu_init.c b/mpc8xx/cpu_init.c index 56500fb..7d91ff5 100644 --- a/mpc8xx/cpu_init.c +++ b/mpc8xx/cpu_init.c @@ -100,7 +100,14 @@ cpu_init_f (volatile immap_t *immr) * has been determined */ +#if defined(CONFIG_SPD823TS) + /* XXX - FIXME - XXX + * I still don't understand why some systems work only with this + * statement here, and others work only without it. + * I offer a free beer to anyone who can explain that to me - wd + */ memctl->memc_br0 = CFG_BR0_PRELIM; /* XXX ??? XXX ??? XXX */ +#endif memctl->memc_or0 = CFG_OR0_REMAP; memctl->memc_or1 = CFG_OR1_REMAP; diff --git a/mpc8xx/kgdb.S b/mpc8xx/kgdb.S new file mode 100644 index 0000000..fec67c5 --- /dev/null +++ b/mpc8xx/kgdb.S @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2000 Murray Jensen + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include "version.h" + +#define CONFIG_8xx 1 /* needed for Linux kernel header files */ +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include +#include + +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + + /* + * cache flushing routines for kgdb + */ + + .globl kgdb_flush_cache_all +kgdb_flush_cache_all: + lis r3, IDC_INVALL@h + mtspr DC_CST, r3 + sync + lis r3, IDC_INVALL@h + mtspr IC_CST, r3 + SYNC + blr + + CACHE_LINE_SIZE = 16 + LG_CACHE_LINE_SIZE = 4 + + .globl kgdb_flush_cache_range +kgdb_flush_cache_range: + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: icbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 2b + SYNC + blr + +#endif /* CFG_CMD_KGDB */ diff --git a/mpc8xx/serial.c b/mpc8xx/serial.c index 38d01f0..d157b1d 100644 --- a/mpc8xx/serial.c +++ b/mpc8xx/serial.c @@ -23,6 +23,9 @@ #include #include +#include + +#if !defined(CONFIG_8xx_CONS_NONE) /* No Console at all */ #if defined(CONFIG_8xx_CONS_SMC1) /* Console on SMC1 */ @@ -36,7 +39,7 @@ #define PROFF_SMC PROFF_SMC2 #define CPM_CR_CH_SMC CPM_CR_CH_SMC2 -#else /* CONFIG_8xx_CONS_SMC? */ +#else /* CONFIG_8xx_CONS_? */ #error "console not correctly defined" #endif @@ -282,3 +285,43 @@ serial_tstc() return(!(rbdf->cbd_sc & BD_SC_EMPTY)); } + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + +void +kgdb_serial_init(void) +{ +#ifdef CONFIG_8xx_CONS_SMC1 + printf("[on SMC1] "); +#endif +#ifdef CONFIG_8xx_CONS_SMC2 + printf("[on SMC2] "); +#endif +} + +void +putDebugChar (int c) +{ + serial_putc (c); +} + +void +putDebugStr (const char *str) +{ + serial_putstr (str); +} + +int +getDebugChar (void) +{ + return serial_getc(); +} + +void +kgdb_interruptible (int yes) +{ + return; +} +#endif /* CFG_CMD_KGDB */ + +#endif /* CONFIG_8xx_CONS_NONE */ diff --git a/mpc8xx/start.S b/mpc8xx/start.S index c8724fc..4a86be9 100644 --- a/mpc8xx/start.S +++ b/mpc8xx/start.S @@ -162,7 +162,7 @@ in_flash: lis r3, CFG_IMMR@h /* position IMMR and */ mtspr 638, r3 /* pass r3 as arg1 to C routine */ - ori r1, r3, 0x3000 /* set up the stack in internal DPRAM */ + ori r1, r3, CFG_INIT_SP_OFFSET /* set up the stack in internal DPRAM */ /* diff --git a/mpc8xx/traps.c b/mpc8xx/traps.c index 227b41d..0181100 100644 --- a/mpc8xx/traps.c +++ b/mpc8xx/traps.c @@ -33,14 +33,19 @@ */ #include +#include #include +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +int (*debugger_exception_handler)(struct pt_regs *) = 0; +#endif + /* Returns 0 if exception not found and fixup otherwise. */ extern unsigned long search_exception_table(unsigned long); /* THIS NEEDS CHANGING to use the board info structure. */ -#define END_OF_MEM 0x00400000 +#define END_OF_MEM 0x02000000 /* * Trap & Exception support @@ -117,6 +122,11 @@ MachineCheckException(struct pt_regs *regs) return; } +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + printf("Machine check in kernel mode.\n"); printf("Caused by (from msr): "); printf("regs %p ",regs); @@ -146,6 +156,10 @@ MachineCheckException(struct pt_regs *regs) void AlignmentException(struct pt_regs *regs) { +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); panic("Alignment Exception"); @@ -154,6 +168,10 @@ AlignmentException(struct pt_regs *regs) void ProgramCheckException(struct pt_regs *regs) { +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); panic("Program Check Exception"); @@ -162,6 +180,10 @@ ProgramCheckException(struct pt_regs *regs) void SoftEmuException(struct pt_regs *regs) { +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); panic("Software Emulation Exception"); @@ -171,6 +193,10 @@ SoftEmuException(struct pt_regs *regs) void UnknownException(struct pt_regs *regs) { +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); _exception(0, regs); diff --git a/ppc/Makefile b/ppc/Makefile index 3f9d3b6..480532a 100644 --- a/ppc/Makefile +++ b/ppc/Makefile @@ -27,7 +27,7 @@ LIB = lib$(ARCH).a AOBJS = ppcstring.o COBJS = ctype.o vsprintf.o extable.o string.o \ - display_options.o zlib.o crc32.o + display_options.o zlib.o crc32.o kgdb.o OBJS = $(AOBJS) $(COBJS) $(LIB): .depend $(OBJS) diff --git a/ppc/kgdb.c b/ppc/kgdb.c new file mode 100644 index 0000000..bdec679 --- /dev/null +++ b/ppc/kgdb.c @@ -0,0 +1,236 @@ +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + +#include +#include +#include + +#define PC_REGNUM 64 +#define SP_REGNUM 1 + +void breakinst(void); + +int +kgdb_setjmp(long *buf) +{ + asm ("mflr 0; stw 0,0(%0);" + "stw 1,4(%0); stw 2,8(%0);" + "mfcr 0; stw 0,12(%0);" + "stmw 13,16(%0)" + : : "r" (buf)); + /* XXX should save fp regs as well */ + return 0; +} + +void +kgdb_longjmp(long *buf, int val) +{ + if (val == 0) + val = 1; + asm ("lmw 13,16(%0);" + "lwz 0,12(%0); mtcrf 0x38,0;" + "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);" + "mtlr 0; mr 3,%1" + : : "r" (buf), "r" (val)); +} + +static inline unsigned long +get_msr(void) +{ + unsigned long msr; + asm volatile("mfmsr %0" : "=r" (msr):); + return msr; +} + +static inline void +set_msr(unsigned long msr) +{ + asm volatile("mtmsr %0" : : "r" (msr)); +} + +/* Convert the SPARC hardware trap type code to a unix signal number. */ +/* + * This table contains the mapping between PowerPC hardware trap types, and + * signals, which are primarily what GDB understands. + */ +static struct hard_trap_info +{ + unsigned int tt; /* Trap type code for powerpc */ + unsigned char signo; /* Signal that we map this trap into */ +} hard_trap_info[] = { + { 0x200, SIGSEGV }, /* machine check */ + { 0x300, SIGSEGV }, /* address error (store) */ + { 0x400, SIGBUS }, /* instruction bus error */ + { 0x500, SIGINT }, /* interrupt */ + { 0x600, SIGBUS }, /* alingment */ + { 0x700, SIGTRAP }, /* breakpoint trap */ + { 0x800, SIGFPE }, /* fpu unavail */ + { 0x900, SIGALRM }, /* decrementer */ + { 0xa00, SIGILL }, /* reserved */ + { 0xb00, SIGILL }, /* reserved */ + { 0xc00, SIGCHLD }, /* syscall */ + { 0xd00, SIGTRAP }, /* single-step/watch */ + { 0xe00, SIGFPE }, /* fp assist */ + { 0, 0} /* Must be last */ +}; + +static int +computeSignal(unsigned int tt) +{ + struct hard_trap_info *ht; + + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + if (ht->tt == tt) + return ht->signo; + + return SIGHUP; /* default for things we don't know about */ +} + +void +kgdb_enter(struct pt_regs *regs, kgdb_data *kdp) +{ + unsigned long msr; + + kdp->private[0] = msr = get_msr(); + set_msr(msr & ~MSR_EE); /* disable interrupts */ + + if (regs->nip == (unsigned long)breakinst) { + /* Skip over breakpoint trap insn */ + regs->nip += 4; + } + + /* reply to host that an exception has occurred */ + kdp->sigval = computeSignal(regs->trap); + + kdp->nregs = 2; + + kdp->regs[0].num = PC_REGNUM; + kdp->regs[0].val = regs->nip; + + kdp->regs[1].num = SP_REGNUM; + kdp->regs[1].val = regs->gpr[SP_REGNUM]; +} + +void +kgdb_exit(struct pt_regs *regs, kgdb_data *kdp) +{ + unsigned long msr = kdp->private[0]; + + if (kdp->extype & KGDBEXIT_WITHADDR) + regs->nip = kdp->exaddr; + + switch (kdp->extype & KGDBEXIT_TYPEMASK) { + + case KGDBEXIT_KILL: + case KGDBEXIT_CONTINUE: + set_msr(msr); + break; + + case KGDBEXIT_SINGLE: + regs->msr |= MSR_SE; +#if 0 + set_msr(msr | MSR_SE); +#endif + break; + } +} + +int +kgdb_trap(struct pt_regs *regs) +{ + return (regs->trap); +} + +/* return the value of the CPU registers. + * some of them are non-PowerPC names :( + * they are stored in gdb like: + * struct { + * u32 gpr[32]; + * f64 fpr[32]; + * u32 pc, ps, cnd, lr; (ps=msr) + * u32 cnt, xer, mq; + * } + */ + +#define SPACE_REQUIRED ((32*4)+(32*8)+(6*4)) + +int +kgdb_getregs(struct pt_regs *regs, char *buf, int max) +{ + int i; + unsigned long *ptr = (unsigned long *)buf; + + if (max < SPACE_REQUIRED) + kgdb_error(KGDBERR_NOSPACE); + + /* General Purpose Regs */ + for (i = 0; i < 32; i++) + *ptr++ = regs->gpr[i]; + + /* Floating Point Regs - FIXME */ + /*ptr = mem2hex((char *)??, ptr, 32 * 8);*/ + for (i = 0; i < 32; i++) { + *ptr++ = 0; + *ptr++ = 0; + } + + /* pc, msr, cr, lr, ctr, xer, (mq is unused) */ + *ptr++ = regs->nip; + *ptr++ = regs->msr; + *ptr++ = regs->ccr; + *ptr++ = regs->link; + *ptr++ = regs->ctr; + *ptr++ = regs->xer; + + return (SPACE_REQUIRED); +} + +/* set the value of the CPU registers */ + +void +kgdb_putregs(struct pt_regs *regs, char *buf, int length) +{ + int i; + unsigned long *ptr = (unsigned long *)buf; + + if (length < SPACE_REQUIRED) + kgdb_error(KGDBERR_NOSPACE); + + /* + * If the stack pointer has moved, you should pray. + * (cause only god can help you). + */ + + /* General Purpose Regs */ + for (i = 0; i < 32; i++) + regs->gpr[i] = *ptr++; + + /* Floating Point Regs - FIXME?? */ + /*ptr = hex2mem(ptr, ??, 32 * 8);*/ + ptr += 32*2; + + /* pc, msr, cr, lr, ctr, xer, (mq is unused) */ + regs->nip = *ptr++; + regs->msr = *ptr++; + regs->ccr = *ptr++; + regs->link = *ptr++; + regs->ctr = *ptr++; + regs->xer = *ptr++; +} + +/* This function will generate a breakpoint exception. It is used at the + beginning of a program to sync up with a debugger and can be used + otherwise as a quick means to stop program execution and "break" into + the debugger. */ + +void +kgdb_breakpoint(void) +{ + asm(" .globl breakinst + breakinst: .long 0x7d821008 + "); +} + +#endif /* CFG_CMD_KGDB */ diff --git a/ppc4xx/start.S b/ppc4xx/start.S index 66e297b..d088933 100644 --- a/ppc4xx/start.S +++ b/ppc4xx/start.S @@ -209,8 +209,8 @@ boot_warm: addi r1,r1,0x0000 mtdccr r1 // data cache - addis r1,r0,0x00ef // set up stack - ori r1,r1,0x0300 // + addis r1,r0,CFG_INIT_RAM_ADDR@h + ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */ GET_GOT /* initialize GOT access */ @@ -280,8 +280,6 @@ boot_warm: ori r4,r4,0x0000 mtdcr ocmdscntl,r4 - ori r1, r3, 0x3000 /* set up the stack in internal DPRAM */ - //----------------------------------------------------------------------- // Initialize the Control 0 register for UART control. // Set UART1 for CTS/RTS and set the UART0 and UART1 internal @@ -298,8 +296,8 @@ boot_warm: //----------------------------------------------------------------------- bl sdram_init - addis r1,r0,OCM_DATA_ADDR@h // set up stack - ori r1,r1,0x0300 // + addis r1,r0,CFG_INIT_RAM_ADDR@h + ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in internal SRAM */ GET_GOT /* initialize GOT access */ @@ -1239,4 +1237,4 @@ sdram_init: blr #endif /* CONFIG_PPC405GP */ - \ No newline at end of file + diff --git a/tools/Makefile b/tools/Makefile index 1b0139d..c97a679 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -27,6 +27,8 @@ BINS = img2srec mkimage OBJS = img2srec.o mkimage.o crc32.o +TOOLSUBDIRS = gdb + # # Use native tools and options # @@ -35,7 +37,7 @@ CFLAGS = $(CPPFLAGS) -I../include CC = $(HOSTCC) MAKEDEPEND = makedepend -all: .depend $(BINS) +all: .depend $(BINS) subdirs img2srec: img2srec.o $(CC) $(CFLAGS) -s -o $@ $^ @@ -49,6 +51,9 @@ crc32.o: crc32.c mkimage.o: mkimage.c $(CC) -g $(CFLAGS) -c $< +subdirs: + @for dir in $(TOOLSUBDIRS) ; do $(MAKE) -C $$dir || exit 1 ; done + ######################################################################### .depend: Makefile $(OBJS:.o=.c) diff --git a/tools/gdb/Makefile b/tools/gdb/Makefile new file mode 100644 index 0000000..68e68ac --- /dev/null +++ b/tools/gdb/Makefile @@ -0,0 +1,62 @@ +# +# (C) Copyright 2000 +# Murray Jensen +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +BINS = gdbsend gdbcont astest + +OBJS = gdbsend.o gdbcont.o astest.o error.o remote.o serial.o + +# +# Use native tools and options +# +CPPFLAGS = -Wall -pedantic -O -I/opt/powerpc/include +CFLAGS = $(CPPFLAGS) +CC = $(HOSTCC) +MAKEDEPEND = makedepend + +all: $(BINS) + +gdbsend: gdbsend.o error.o remote.o serial.o + $(CC) $(CFLAGS) -o $@ $^ + +gdbcont: gdbcont.o error.o remote.o serial.o + $(CC) $(CFLAGS) -o $@ $^ + +astest: astest.o error.o + $(CC) $(CFLAGS) -o $@ $^ -L/opt/powerpc/lib -lbfd -liberty + +clean: + rm -f $(OBJS) + +distclean: clean + rm -f $(BINS) core *.bak .depend + +######################################################################### + +.depend: Makefile $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) -I../include $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/tools/gdb/astest.c b/tools/gdb/astest.c new file mode 100644 index 0000000..4921940 --- /dev/null +++ b/tools/gdb/astest.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include "error.h" + +int verbose = 0; + +void +process_section(bfd *abfd, asection *sect, PTR obj) +{ + printf("Section '%s':\n", sect->name); + + printf("\tindex=%d, flags=%x\n", sect->index, sect->flags); + +#if 0 + printf("\tuser_set_vma=%u, reloc_done=%u, linker_mark=%u, gc_mark=%u\n", + (unsigned long)sect->user_set_vma, (unsigned long)sect->reloc_done, + (unsigned long)sect->linker_mark, (unsigned long)sect->gc_mark); +#else + printf("\tuser_set_vma=%u, reloc_done=%u\n", + (unsigned int)sect->user_set_vma, (unsigned int)sect->reloc_done); +#endif + + printf("\tvma=%08lx, lma=%08lx\n", sect->vma, sect->lma); + + printf("\tcooked_size=%ld, raw_size=%ld, output_offset=%ld\n", + sect->_cooked_size, sect->_raw_size, sect->output_offset); + + printf("\talignment_power=%d, reloc_count=%d, filepos=%ld\n", + sect->alignment_power, sect->reloc_count, sect->filepos); + + printf("\trel_filepos=%ld, line_filepos=%ld, lineno_count=%d\n", + sect->rel_filepos, sect->line_filepos, sect->lineno_count); + + printf("\tmoving_line_filepos=%ld, target_index=%d\n", + sect->moving_line_filepos, sect->target_index); +} + +int +main(int ac, char **av) +{ + int c, ifd; + char *ifn; + bfd *bfdp; + + if ((pname = strrchr(av[0], '/')) == NULL) + pname = av[0]; + else + pname++; + + while ((c = getopt(ac, av, "v")) != EOF) + switch (c) { + + case 'v': + verbose = 1; + break; + + default: + usage: + fprintf(stderr, "Usage: %s [-v] imagefile\n", pname); + exit(1); + } + if (optind != ac - 1) + goto usage; + + ifn = av[optind]; + + if (verbose) + fprintf(stderr, "Opening file...\n"); + + if ((ifd = open(ifn, O_RDONLY)) < 0) + Perror("can't open image file '%s'", ifn); + + if ((bfdp = bfd_fdopenr(ifn, "elf32-powerpc", ifd)) == NULL) { + bfd_perror(ifn); + close(ifd); + Error("bfd_fdopenr of file '%s' failed", ifn); + } + bfdp->cacheable = true; + + if (!bfd_check_format(bfdp, bfd_object) || + (bfd_get_file_flags(bfdp) & EXEC_P) == 0) { + bfd_close(bfdp); + Error("file '%s' is not an executable object file (%s,0x%x)", ifn, + bfd_format_string(bfd_get_format(bfdp)), bfd_get_file_flags(bfdp)); + } + + printf("file '%s' is type '%s'...\n", ifn, bfd_get_target(bfdp)); + + bfd_map_over_sections(bfdp, process_section, NULL);; + + bfd_close(bfdp); + + if (verbose) + fprintf(stderr, "Done.\n"); + + return (0); +} diff --git a/tools/gdb/error.c b/tools/gdb/error.c new file mode 100644 index 0000000..aea2901 --- /dev/null +++ b/tools/gdb/error.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include "error.h" + +char *pname; + +void +Warning(char *fmt, ...) +{ + va_list args; + + fprintf(stderr, "%s: WARNING: ", pname); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\n"); +} + +void +Error(char *fmt, ...) +{ + va_list args; + + fprintf(stderr, "%s: ERROR: ", pname); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + fprintf(stderr, "\n"); + + exit(1); +} + +void +Perror(char *fmt, ...) +{ + va_list args; + int e = errno; + char *p; + + fprintf(stderr, "%s: ERROR: ", pname); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + if ((p = strerror(e)) == NULL || *p == '\0') + fprintf(stderr, ": Unknown Error (%d)\n", e); + else + fprintf(stderr, ": %s\n", p); + + exit(1); +} diff --git a/tools/gdb/error.h b/tools/gdb/error.h new file mode 100644 index 0000000..907709f --- /dev/null +++ b/tools/gdb/error.h @@ -0,0 +1,7 @@ +#include + +extern char *pname; + +extern void Warning(char *, ...); +extern void Error(char *, ...); +extern void Perror(char *, ...); diff --git a/tools/gdb/gdbcont.c b/tools/gdb/gdbcont.c new file mode 100644 index 0000000..ee9553c --- /dev/null +++ b/tools/gdb/gdbcont.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include "serial.h" +#include "error.h" +#include "remote.h" + +char *serialdev = "/dev/term/b"; +speed_t speed = B230400; +int verbose = 0; + +int +main(int ac, char **av) +{ + int c, sfd; + + if ((pname = strrchr(av[0], '/')) == NULL) + pname = av[0]; + else + pname++; + + while ((c = getopt(ac, av, "b:p:v")) != EOF) + switch (c) { + + case 'b': + if ((speed = cvtspeed(optarg)) == B0) + Error("can't decode baud rate specified in -b option"); + break; + + case 'p': + serialdev = optarg; + break; + + case 'v': + verbose = 1; + break; + + default: + usage: + fprintf(stderr, "Usage: %s [-b bps] [-p dev] [-v]\n", pname); + exit(1); + } + if (optind != ac) + goto usage; + + if (verbose) + fprintf(stderr, "Opening serial port and sending continue...\n"); + + if ((sfd = serialopen(serialdev, speed)) < 0) + Perror("open of serial device '%s' failed", serialdev); + + remote_desc = sfd; + remote_reset(); + remote_continue(); + + if (serialclose(sfd) < 0) + Perror("close of serial device '%s' failed", serialdev); + + if (verbose) + fprintf(stderr, "Done.\n"); + + return (0); +} diff --git a/tools/gdb/gdbsend.c b/tools/gdb/gdbsend.c new file mode 100644 index 0000000..d46ab48 --- /dev/null +++ b/tools/gdb/gdbsend.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include "serial.h" +#include "error.h" +#include "remote.h" + +char *serialdev = "/dev/term/b"; +speed_t speed = B230400; +int verbose = 0, docont = 0; +unsigned long addr = 0x10000UL; + +int +main(int ac, char **av) +{ + int c, sfd, ifd; + char *ifn, *image; + struct stat ist; + + if ((pname = strrchr(av[0], '/')) == NULL) + pname = av[0]; + else + pname++; + + while ((c = getopt(ac, av, "a:b:cp:v")) != EOF) + switch (c) { + + case 'a': { + char *ep; + + addr = strtol(optarg, &ep, 0); + if (ep == optarg || *ep != '\0') + Error("can't decode address specified in -a option"); + break; + } + + case 'b': + if ((speed = cvtspeed(optarg)) == B0) + Error("can't decode baud rate specified in -b option"); + break; + + case 'c': + docont = 1; + break; + + case 'p': + serialdev = optarg; + break; + + case 'v': + verbose = 1; + break; + + default: + usage: + fprintf(stderr, + "Usage: %s [-a addr] [-b bps] [-c] [-p dev] [-v] imagefile\n", + pname); + exit(1); + } + + if (optind != ac - 1) + goto usage; + ifn = av[optind++]; + + if (verbose) + fprintf(stderr, "Opening file and reading image...\n"); + + if ((ifd = open(ifn, O_RDONLY)) < 0) + Perror("can't open kernel image file '%s'", ifn); + + if (fstat(ifd, &ist) < 0) + Perror("fstat '%s' failed", ifn); + + if ((image = (char *)malloc(ist.st_size)) == NULL) + Perror("can't allocate %ld bytes for image", ist.st_size); + + if ((c = read(ifd, image, ist.st_size)) < 0) + Perror("read of %d bytes from '%s' failed", ist.st_size, ifn); + + if (c != ist.st_size) + Error("read of %ld bytes from '%s' failed (%d)", ist.st_size, ifn, c); + + if (close(ifd) < 0) + Perror("close of '%s' failed", ifn); + + if (verbose) + fprintf(stderr, "Opening serial port and sending image...\n"); + + if ((sfd = serialopen(serialdev, speed)) < 0) + Perror("open of serial device '%s' failed", serialdev); + + remote_desc = sfd; + remote_reset(); + remote_write_bytes(addr, image, ist.st_size); + + if (docont) { + if (verbose) + fprintf(stderr, "[continue]"); + remote_continue(); + } + + if (serialclose(sfd) < 0) + Perror("close of serial device '%s' failed", serialdev); + + if (verbose) + fprintf(stderr, "Done.\n"); + + return (0); +} diff --git a/tools/gdb/remote.c b/tools/gdb/remote.c new file mode 100644 index 0000000..d736c65 --- /dev/null +++ b/tools/gdb/remote.c @@ -0,0 +1,896 @@ +/* + * taken from gdb/remote.c + * + * I am only interested in the write to memory stuff - everything else + * has been ripped out + * + * all the copyright notices etc have been left in + */ + +/* enough so that it will compile */ +#include +#include +#include +#include +#include +#include "serial.h" +#include "error.h" +#include "remote.h" +#define REGISTER_BYTES 0 +#define fprintf_unfiltered fprintf +#define fprintf_filtered fprintf +#define fputs_unfiltered fputs +#define fputs_filtered fputs +#define fputc_unfiltered fputc +#define fputc_filtered fputc +#define printf_unfiltered printf +#define printf_filtered printf +#define puts_unfiltered puts +#define puts_filtered puts +#define putchar_unfiltered putchar +#define putchar_filtered putchar +#define fputstr_unfiltered(a,b,c) fputs((a), (c)) +#define gdb_stdlog stderr +#define SERIAL_READCHAR(fd,timo) serialreadchar((fd), (timo)) +#define SERIAL_WRITE(fd, addr, len) serialwrite((fd), (addr), (len)) +#define error Error +#define perror_with_name Perror +#define gdb_flush fflush +#define max(a,b) (((a)>(b))?(a):(b)) +#define min(a,b) (((a)<(b))?(a):(b)) +#define target_mourn_inferior() {} +#define ULONGEST unsigned long +#define CORE_ADDR unsigned long + +static int putpkt (char *); +static int putpkt_binary(char *, int); +static void getpkt (char *, int); + +static int remote_debug = 0, remote_register_buf_size = 0, watchdog = 0; + +int remote_desc = -1, remote_timeout = 10; + +static void +fputstrn_unfiltered(char *s, int n, int x, FILE *fp) +{ + while (n-- > 0) + fputc(*s++, fp); +} + +void +remote_reset(void) +{ + SERIAL_WRITE(remote_desc, "+", 1); +} + +void +remote_continue(void) +{ + putpkt("c"); +} + +/* Remote target communications for serial-line targets in custom GDB protocol + Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ +/* *INDENT-OFF* */ +/* Remote communication protocol. + + A debug packet whose contents are + is encapsulated for transmission in the form: + + $ # CSUM1 CSUM2 + + must be ASCII alphanumeric and cannot include characters + '$' or '#'. If starts with two characters followed by + ':', then the existing stubs interpret this as a sequence number. + + CSUM1 and CSUM2 are ascii hex representation of an 8-bit + checksum of , the most significant nibble is sent first. + the hex digits 0-9,a-f are used. + + Receiver responds with: + + + - if CSUM is correct and ready for next packet + - - if CSUM is incorrect + + is as follows: + Most values are encoded in ascii hex digits. Signal numbers are according + to the numbering in target.h. + + Request Packet + + set thread Hct... Set thread for subsequent operations. + c = 'c' for thread used in step and + continue; t... can be -1 for all + threads. + c = 'g' for thread used in other + operations. If zero, pick a thread, + any thread. + reply OK for success + ENN for an error. + + read registers g + reply XX....X Each byte of register data + is described by two hex digits. + Registers are in the internal order + for GDB, and the bytes in a register + are in the same order the machine uses. + or ENN for an error. + + write regs GXX..XX Each byte of register data + is described by two hex digits. + reply OK for success + ENN for an error + + write reg Pn...=r... Write register n... with value r..., + which contains two hex digits for each + byte in the register (target byte + order). + reply OK for success + ENN for an error + (not supported by all stubs). + + read mem mAA..AA,LLLL AA..AA is address, LLLL is length. + reply XX..XX XX..XX is mem contents + Can be fewer bytes than requested + if able to read only part of the data. + or ENN NN is errno + + write mem MAA..AA,LLLL:XX..XX + AA..AA is address, + LLLL is number of bytes, + XX..XX is data + reply OK for success + ENN for an error (this includes the case + where only part of the data was + written). + + write mem XAA..AA,LLLL:XX..XX + (binary) AA..AA is address, + LLLL is number of bytes, + XX..XX is binary data + reply OK for success + ENN for an error + + continue cAA..AA AA..AA is address to resume + If AA..AA is omitted, + resume at same address. + + step sAA..AA AA..AA is address to resume + If AA..AA is omitted, + resume at same address. + + continue with Csig;AA..AA Continue with signal sig (hex signal + signal number). If ;AA..AA is omitted, + resume at same address. + + step with Ssig;AA..AA Like 'C' but step not continue. + signal + + last signal ? Reply the current reason for stopping. + This is the same reply as is generated + for step or cont : SAA where AA is the + signal number. + + detach D Reply OK. + + There is no immediate reply to step or cont. + The reply comes when the machine stops. + It is SAA AA is the signal number. + + or... TAAn...:r...;n...:r...;n...:r...; + AA = signal number + n... = register number (hex) + r... = register contents + n... = `thread' + r... = thread process ID. This is + a hex integer. + n... = other string not starting + with valid hex digit. + gdb should ignore this n,r pair + and go on to the next. This way + we can extend the protocol. + or... WAA The process exited, and AA is + the exit status. This is only + applicable for certains sorts of + targets. + or... XAA The process terminated with signal + AA. + or (obsolete) NAA;tttttttt;dddddddd;bbbbbbbb + AA = signal number + tttttttt = address of symbol "_start" + dddddddd = base of data section + bbbbbbbb = base of bss section. + Note: only used by Cisco Systems + targets. The difference between this + reply and the "qOffsets" query is that + the 'N' packet may arrive spontaneously + whereas the 'qOffsets' is a query + initiated by the host debugger. + or... OXX..XX XX..XX is hex encoding of ASCII data. This + can happen at any time while the + program is running and the debugger + should continue to wait for + 'W', 'T', etc. + + thread alive TXX Find out if the thread XX is alive. + reply OK thread is still alive + ENN thread is dead + + remote restart RXX Restart the remote server + + extended ops ! Use the extended remote protocol. + Sticky -- only needs to be set once. + + kill request k + + toggle debug d toggle debug flag (see 386 & 68k stubs) + reset r reset -- see sparc stub. + reserved On other requests, the stub should + ignore the request and send an empty + response ($#). This way + we can extend the protocol and GDB + can tell whether the stub it is + talking to uses the old or the new. + search tAA:PP,MM Search backwards starting at address + AA for a match with pattern PP and + mask MM. PP and MM are 4 bytes. + Not supported by all stubs. + + general query qXXXX Request info about XXXX. + general set QXXXX=yyyy Set value of XXXX to yyyy. + query sect offs qOffsets Get section offsets. Reply is + Text=xxx;Data=yyy;Bss=zzz + + Responses can be run-length encoded to save space. A '*' means that + the next character is an ASCII encoding giving a repeat count which + stands for that many repititions of the character preceding the '*'. + The encoding is n+29, yielding a printable character where n >=3 + (which is where rle starts to win). Don't use an n > 126. + + So + "0* " means the same as "0000". */ +/* *INDENT-ON* */ + +/* This variable (available to the user via "set remotebinarydownload") + dictates whether downloads are sent in binary (via the 'X' packet). + We assume that the stub can, and attempt to do it. This will be cleared if + the stub does not understand it. This switch is still needed, though + in cases when the packet is supported in the stub, but the connection + does not allow it (i.e., 7-bit serial connection only). */ +static int remote_binary_download = 1; + +/* Have we already checked whether binary downloads work? */ +static int remote_binary_checked; + +/* Maximum number of bytes to read/write at once. The value here + is chosen to fill up a packet (the headers account for the 32). */ +#define MAXBUFBYTES(N) (((N)-32)/2) + +/* Having this larger than 400 causes us to be incompatible with m68k-stub.c + and i386-stub.c. Normally, no one would notice because it only matters + for writing large chunks of memory (e.g. in downloads). Also, this needs + to be more than 400 if required to hold the registers (see below, where + we round it up based on REGISTER_BYTES). */ +/* Round up PBUFSIZ to hold all the registers, at least. */ +#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \ + ? (REGISTER_BYTES * 2 + 32) \ + : 400) + + +/* This variable sets the number of bytes to be written to the target + in a single packet. Normally PBUFSIZ is satisfactory, but some + targets need smaller values (perhaps because the receiving end + is slow). */ + +static int remote_write_size = 0x7fffffff; + +/* This variable sets the number of bits in an address that are to be + sent in a memory ("M" or "m") packet. Normally, after stripping + leading zeros, the entire address would be sent. This variable + restricts the address to REMOTE_ADDRESS_SIZE bits. HISTORY: The + initial implementation of remote.c restricted the address sent in + memory packets to ``host::sizeof long'' bytes - (typically 32 + bits). Consequently, for 64 bit targets, the upper 32 bits of an + address was never sent. Since fixing this bug may cause a break in + some remote targets this variable is principly provided to + facilitate backward compatibility. */ + +static int remote_address_size; + +/* Convert hex digit A to a number. */ + +static int +fromhex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + else { + error ("Reply contains invalid hex digit %d", a); + return -1; + } +} + +/* Convert number NIB to a hex digit. */ + +static int +tohex (int nib) +{ + if (nib < 10) + return '0' + nib; + else + return 'a' + nib - 10; +} + +/* Return the number of hex digits in num. */ + +static int +hexnumlen (ULONGEST num) +{ + int i; + + for (i = 0; num != 0; i++) + num >>= 4; + + return max (i, 1); +} + +/* Set BUF to the hex digits representing NUM. */ + +static int +hexnumstr (char *buf, ULONGEST num) +{ + int i; + int len = hexnumlen (num); + + buf[len] = '\0'; + + for (i = len - 1; i >= 0; i--) + { + buf[i] = "0123456789abcdef"[(num & 0xf)]; + num >>= 4; + } + + return len; +} + +/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */ + +static CORE_ADDR +remote_address_masked (CORE_ADDR addr) +{ + if (remote_address_size > 0 + && remote_address_size < (sizeof (ULONGEST) * 8)) + { + /* Only create a mask when that mask can safely be constructed + in a ULONGEST variable. */ + ULONGEST mask = 1; + mask = (mask << remote_address_size) - 1; + addr &= mask; + } + return addr; +} + +/* Determine whether the remote target supports binary downloading. + This is accomplished by sending a no-op memory write of zero length + to the target at the specified address. It does not suffice to send + the whole packet, since many stubs strip the eighth bit and subsequently + compute a wrong checksum, which causes real havoc with remote_write_bytes. + + NOTE: This can still lose if the serial line is not eight-bit clean. In + cases like this, the user should clear "remotebinarydownload". */ +static void +check_binary_download (CORE_ADDR addr) +{ + if (remote_binary_download && !remote_binary_checked) + { + char *buf = alloca (PBUFSIZ); + char *p; + remote_binary_checked = 1; + + p = buf; + *p++ = 'X'; + p += hexnumstr (p, (ULONGEST) addr); + *p++ = ','; + p += hexnumstr (p, (ULONGEST) 0); + *p++ = ':'; + *p = '\0'; + + putpkt_binary (buf, (int) (p - buf)); + getpkt (buf, 0); + + if (buf[0] == '\0') + remote_binary_download = 0; + } + + if (remote_debug) + { + if (remote_binary_download) + fprintf_unfiltered (gdb_stdlog, + "binary downloading suppported by target\n"); + else + fprintf_unfiltered (gdb_stdlog, + "binary downloading NOT suppported by target\n"); + } +} + +/* Write memory data directly to the remote machine. + This does not inform the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of bytes. + + Returns number of bytes transferred, or 0 for error. */ + +int +remote_write_bytes (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + unsigned char *buf = alloca (PBUFSIZ); + int max_buf_size; /* Max size of packet output buffer */ + int origlen; + extern int verbose; + + /* Verify that the target can support a binary download */ + check_binary_download (memaddr); + + /* Chop the transfer down if necessary */ + + max_buf_size = min (remote_write_size, PBUFSIZ); + if (remote_register_buf_size != 0) + max_buf_size = min (max_buf_size, remote_register_buf_size); + + /* Subtract header overhead from max payload size - $M,:#nn */ + max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4; + + origlen = len; + while (len > 0) + { + unsigned char *p, *plen; + int todo; + int i; + + /* construct "M"","":" */ + /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */ + memaddr = remote_address_masked (memaddr); + p = buf; + if (remote_binary_download) + { + *p++ = 'X'; + todo = min (len, max_buf_size); + } + else + { + *p++ = 'M'; + todo = min (len, max_buf_size / 2); /* num bytes that will fit */ + } + + p += hexnumstr ((char *)p, (ULONGEST) memaddr); + *p++ = ','; + + plen = p; /* remember where len field goes */ + p += hexnumstr ((char *)p, (ULONGEST) todo); + *p++ = ':'; + *p = '\0'; + + /* We send target system values byte by byte, in increasing byte + addresses, each byte encoded as two hex characters (or one + binary character). */ + if (remote_binary_download) + { + int escaped = 0; + for (i = 0; + (i < todo) && (i + escaped) < (max_buf_size - 2); + i++) + { + switch (myaddr[i] & 0xff) + { + case '$': + case '#': + case 0x7d: + /* These must be escaped */ + escaped++; + *p++ = 0x7d; + *p++ = (myaddr[i] & 0xff) ^ 0x20; + break; + default: + *p++ = myaddr[i] & 0xff; + break; + } + } + + if (i < todo) + { + /* Escape chars have filled up the buffer prematurely, + and we have actually sent fewer bytes than planned. + Fix-up the length field of the packet. */ + + /* FIXME: will fail if new len is a shorter string than + old len. */ + + plen += hexnumstr ((char *)plen, (ULONGEST) i); + *plen++ = ':'; + } + } + else + { + for (i = 0; i < todo; i++) + { + *p++ = tohex ((myaddr[i] >> 4) & 0xf); + *p++ = tohex (myaddr[i] & 0xf); + } + *p = '\0'; + } + + putpkt_binary ((char *)buf, (int) (p - buf)); + getpkt ((char *)buf, 0); + + if (buf[0] == 'E') + { + /* There is no correspondance between what the remote protocol uses + for errors and errno codes. We would like a cleaner way of + representing errors (big enough to include errno codes, bfd_error + codes, and others). But for now just return EIO. */ + errno = EIO; + return 0; + } + + /* Increment by i, not by todo, in case escape chars + caused us to send fewer bytes than we'd planned. */ + myaddr += i; + memaddr += i; + len -= i; + + if (verbose) + putc('.', stderr); + } + return origlen; +} + +/* Stuff for dealing with the packets which are part of this protocol. + See comment at top of file for details. */ + +/* Read a single character from the remote end, masking it down to 7 bits. */ + +static int +readchar (int timeout) +{ + int ch; + + ch = SERIAL_READCHAR (remote_desc, timeout); + + switch (ch) + { + case SERIAL_EOF: + error ("Remote connection closed"); + case SERIAL_ERROR: + perror_with_name ("Remote communication error"); + case SERIAL_TIMEOUT: + return ch; + default: + return ch & 0x7f; + } +} + +static int +putpkt (buf) + char *buf; +{ + return putpkt_binary (buf, strlen (buf)); +} + +/* Send a packet to the remote machine, with error checking. The data + of the packet is in BUF. The string in BUF can be at most PBUFSIZ - 5 + to account for the $, # and checksum, and for a possible /0 if we are + debugging (remote_debug) and want to print the sent packet as a string */ + +static int +putpkt_binary (buf, cnt) + char *buf; + int cnt; +{ + int i; + unsigned char csum = 0; + char *buf2 = alloca (PBUFSIZ); + char *junkbuf = alloca (PBUFSIZ); + + int ch; + int tcount = 0; + char *p; + + /* Copy the packet into buffer BUF2, encapsulating it + and giving it a checksum. */ + + if (cnt > BUFSIZ - 5) /* Prosanity check */ + abort (); + + p = buf2; + *p++ = '$'; + + for (i = 0; i < cnt; i++) + { + csum += buf[i]; + *p++ = buf[i]; + } + *p++ = '#'; + *p++ = tohex ((csum >> 4) & 0xf); + *p++ = tohex (csum & 0xf); + + /* Send it over and over until we get a positive ack. */ + + while (1) + { + int started_error_output = 0; + + if (remote_debug) + { + *p = '\0'; + fprintf_unfiltered (gdb_stdlog, "Sending packet: "); + fputstrn_unfiltered (buf2, p - buf2, 0, gdb_stdlog); + fprintf_unfiltered (gdb_stdlog, "..."); + gdb_flush (gdb_stdlog); + } + if (SERIAL_WRITE (remote_desc, buf2, p - buf2)) + perror_with_name ("putpkt: write failed"); + + /* read until either a timeout occurs (-2) or '+' is read */ + while (1) + { + ch = readchar (remote_timeout); + + if (remote_debug) + { + switch (ch) + { + case '+': + case SERIAL_TIMEOUT: + case '$': + if (started_error_output) + { + putchar_unfiltered ('\n'); + started_error_output = 0; + } + } + } + + switch (ch) + { + case '+': + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "Ack\n"); + return 1; + case SERIAL_TIMEOUT: + tcount++; + if (tcount > 3) + return 0; + break; /* Retransmit buffer */ + case '$': + { + /* It's probably an old response, and we're out of sync. + Just gobble up the packet and ignore it. */ + getpkt (junkbuf, 0); + continue; /* Now, go look for + */ + } + default: + if (remote_debug) + { + if (!started_error_output) + { + started_error_output = 1; + fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: "); + } + fputc_unfiltered (ch & 0177, gdb_stdlog); + } + continue; + } + break; /* Here to retransmit */ + } + +#if 0 + /* This is wrong. If doing a long backtrace, the user should be + able to get out next time we call QUIT, without anything as + violent as interrupt_query. If we want to provide a way out of + here without getting to the next QUIT, it should be based on + hitting ^C twice as in remote_wait. */ + if (quit_flag) + { + quit_flag = 0; + interrupt_query (); + } +#endif + } +} + +/* Come here after finding the start of the frame. Collect the rest + into BUF, verifying the checksum, length, and handling run-length + compression. Returns 0 on any error, 1 on success. */ + +static int +read_frame (char *buf) +{ + unsigned char csum; + char *bp; + int c; + + csum = 0; + bp = buf; + + while (1) + { + c = readchar (remote_timeout); + + switch (c) + { + case SERIAL_TIMEOUT: + if (remote_debug) + fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog); + return 0; + case '$': + if (remote_debug) + fputs_filtered ("Saw new packet start in middle of old one\n", + gdb_stdlog); + return 0; /* Start a new packet, count retries */ + case '#': + { + unsigned char pktcsum; + + *bp = '\000'; + + pktcsum = fromhex (readchar (remote_timeout)) << 4; + pktcsum |= fromhex (readchar (remote_timeout)); + + if (csum == pktcsum) + { + return 1; + } + + if (remote_debug) + { + fprintf_filtered (gdb_stdlog, + "Bad checksum, sentsum=0x%x, csum=0x%x, buf=", + pktcsum, csum); + fputs_filtered (buf, gdb_stdlog); + fputs_filtered ("\n", gdb_stdlog); + } + return 0; + } + case '*': /* Run length encoding */ + csum += c; + c = readchar (remote_timeout); + csum += c; + c = c - ' ' + 3; /* Compute repeat count */ + + if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1) + { + memset (bp, *(bp - 1), c); + bp += c; + continue; + } + + *bp = '\0'; + printf_filtered ("Repeat count %d too large for buffer: ", c); + puts_filtered (buf); + puts_filtered ("\n"); + return 0; + default: + if (bp < buf + PBUFSIZ - 1) + { + *bp++ = c; + csum += c; + continue; + } + + *bp = '\0'; + puts_filtered ("Remote packet too long: "); + puts_filtered (buf); + puts_filtered ("\n"); + + return 0; + } + } +} + +/* Read a packet from the remote machine, with error checking, and + store it in BUF. BUF is expected to be of size PBUFSIZ. If + FOREVER, wait forever rather than timing out; this is used while + the target is executing user code. */ + +static void +getpkt (buf, forever) + char *buf; + int forever; +{ + int c; + int tries; + int timeout; + int val; + + strcpy (buf, "timeout"); + + if (forever) + { + timeout = watchdog > 0 ? watchdog : -1; + } + + else + timeout = remote_timeout; + +#define MAX_TRIES 3 + + for (tries = 1; tries <= MAX_TRIES; tries++) + { + /* This can loop forever if the remote side sends us characters + continuously, but if it pauses, we'll get a zero from readchar + because of timeout. Then we'll count that as a retry. */ + + /* Note that we will only wait forever prior to the start of a packet. + After that, we expect characters to arrive at a brisk pace. They + should show up within remote_timeout intervals. */ + + do + { + c = readchar (timeout); + + if (c == SERIAL_TIMEOUT) + { + if (forever) /* Watchdog went off. Kill the target. */ + { + target_mourn_inferior (); + error ("Watchdog has expired. Target detached.\n"); + } + if (remote_debug) + fputs_filtered ("Timed out.\n", gdb_stdlog); + goto retry; + } + } + while (c != '$'); + + /* We've found the start of a packet, now collect the data. */ + + val = read_frame (buf); + + if (val == 1) + { + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, "Packet received: "); + fputstr_unfiltered (buf, 0, gdb_stdlog); + fprintf_unfiltered (gdb_stdlog, "\n"); + } + SERIAL_WRITE (remote_desc, "+", 1); + return; + } + + /* Try the whole thing again. */ + retry: + SERIAL_WRITE (remote_desc, "-", 1); + } + + /* We have tried hard enough, and just can't receive the packet. Give up. */ + + printf_unfiltered ("Ignoring packet error, continuing...\n"); + SERIAL_WRITE (remote_desc, "+", 1); +} diff --git a/tools/gdb/remote.h b/tools/gdb/remote.h new file mode 100644 index 0000000..bfc4a1f --- /dev/null +++ b/tools/gdb/remote.h @@ -0,0 +1,5 @@ +extern int remote_desc, remote_timeout; + +extern void remote_reset(void); +extern void remote_continue(void); +extern int remote_write_bytes(unsigned long, char *, int); diff --git a/tools/gdb/serial.c b/tools/gdb/serial.c new file mode 100644 index 0000000..59736ed --- /dev/null +++ b/tools/gdb/serial.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include "serial.h" + +static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 }; + +static struct speedmap { + char *str; + speed_t val; +} speedmap[] = { + { "50", B50 }, { "75", B75 }, { "110", B110 }, + { "134", B134 }, { "150", B150 }, { "200", B200 }, + { "300", B300 }, { "600", B600 }, { "1200", B1200 }, + { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, + { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 }, + { "57600", B57600 }, +#ifdef B76800 + { "76800", B76800 }, +#endif + { "115200", B115200 }, +#ifdef B153600 + { "153600", B153600 }, +#endif + { "230400", B230400 }, +#ifdef B307200 + { "307200", B307200 }, +#endif + { "460800", B460800 } +}; +static int nspeeds = sizeof speedmap / sizeof speedmap[0]; + +speed_t +cvtspeed(char *str) +{ + struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds]; + + while (smp < esmp) { + if (strcmp(str, smp->str) == 0) + return (smp->val); + smp++; + } + return B0; +} + +int +serialopen(char *device, speed_t speed) +{ + int fd; + + if (cfsetospeed(&tios, speed) < 0) + return -1; + + if ((fd = open(device, O_RDWR)) < 0) + return -1; + + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { + (void)close(fd); + return -1; + } + + return fd; +} + +int +serialreadchar(int fd, int timeout) +{ + fd_set fds; + struct timeval tv; + int n; + char ch; + + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + + /* this is a fucking horrible quick hack - fix this */ + + if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0) + return SERIAL_ERROR; + + if (n == 0) + return SERIAL_TIMEOUT; + + if ((n = read(fd, &ch, 1)) < 0) + return SERIAL_ERROR; + + if (n == 0) + return SERIAL_EOF; + + return ch; +} + +int +serialwrite(int fd, char *buf, int len) +{ + int n; + + do { + n = write(fd, buf, len); + if (n < 0) + return 1; + len -= n; + buf += n; + } while (len > 0); + return 0; +} + +int +serialclose(int fd) +{ + return close(fd); +} diff --git a/tools/gdb/serial.h b/tools/gdb/serial.h new file mode 100644 index 0000000..60629bd --- /dev/null +++ b/tools/gdb/serial.h @@ -0,0 +1,11 @@ +#include + +#define SERIAL_ERROR -1 /* General error, see errno for details */ +#define SERIAL_TIMEOUT -2 +#define SERIAL_EOF -3 + +extern speed_t cvtspeed(char *); +extern int serialopen(char *, speed_t); +extern int serialreadchar(int, int); +extern int serialwrite(int, char *, int); +extern int serialclose(int); diff --git a/tools/img2srec.c b/tools/img2srec.c index 028c04b..b153d0d 100644 --- a/tools/img2srec.c +++ b/tools/img2srec.c @@ -58,6 +58,7 @@ #include #include #include +#include extern int errno; @@ -291,11 +292,11 @@ static void ConvertELF(char* fileName, DWORD loadOffset) getPtr = ExtractBlock(sizeof elfHeader.e_ident, elfHeader.e_ident, rxBlock); getPtr = ExtractWord(&elfHeader.e_type, getPtr); getPtr = ExtractWord(&elfHeader.e_machine, getPtr); - getPtr = ExtractLong(&elfHeader.e_version, getPtr); - getPtr = ExtractLong(&elfHeader.e_entry, getPtr); - getPtr = ExtractLong(&elfHeader.e_phoff, getPtr); - getPtr = ExtractLong(&elfHeader.e_shoff, getPtr); - getPtr = ExtractLong(&elfHeader.e_flags, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_version, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_entry, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_phoff, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_shoff, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_flags, getPtr); getPtr = ExtractWord(&elfHeader.e_ehsize, getPtr); getPtr = ExtractWord(&elfHeader.e_phentsize, getPtr); getPtr = ExtractWord(&elfHeader.e_phnum, getPtr); @@ -318,16 +319,16 @@ static void ConvertELF(char* fileName, DWORD loadOffset) fseek(file, elfHeader.e_shoff, SEEK_SET); for (i = 0; i < elfHeader.e_shnum; i++) { rxCount = fread(rxBlock, 1, sizeof sectHeader[0], file); - getPtr = ExtractLong(§Header[i].sh_name, rxBlock); - getPtr = ExtractLong(§Header[i].sh_type, getPtr); - getPtr = ExtractLong(§Header[i].sh_flags, getPtr); - getPtr = ExtractLong(§Header[i].sh_addr, getPtr); - getPtr = ExtractLong(§Header[i].sh_offset, getPtr); - getPtr = ExtractLong(§Header[i].sh_size, getPtr); - getPtr = ExtractLong(§Header[i].sh_link, getPtr); - getPtr = ExtractLong(§Header[i].sh_info, getPtr); - getPtr = ExtractLong(§Header[i].sh_addralign, getPtr); - getPtr = ExtractLong(§Header[i].sh_entsize, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_name, rxBlock); + getPtr = ExtractLong((DWORD *)§Header[i].sh_type, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_flags, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_addr, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_offset, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_size, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_link, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_info, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_addralign, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_entsize, getPtr); if (rxCount != sizeof sectHeader[0]) { fclose(file); fprintf (stderr, "*** illegal file format\n"); diff --git a/tools/mkimage.c b/tools/mkimage.c index 8cb4e5a..8d4eaf0 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -4,8 +4,8 @@ * Wolfgang Denk, wd@denx.de * All rights reserved. * - * $Date: 2000/10/07 13:34:15 $ - * $Revision: 1.6 $ + * $Date: 2000/10/11 21:40:06 $ + * $Revision: 1.7 $ */ #include @@ -242,7 +242,8 @@ NXTARG: ; exit (EXIT_FAILURE); } - ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, ifd, 0); if ((caddr_t)ptr == (caddr_t)-1) { fprintf (stderr, "%s: Can't read %s: %s\n", cmdname, imagefile, strerror(errno)); @@ -287,7 +288,7 @@ NXTARG: ; /* for multi-file images we need the data part, too */ print_header ((image_header_t *)ptr); - (void) munmap(ptr, sbuf.st_size); + (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); exit (EXIT_SUCCESS); @@ -376,7 +377,8 @@ NXTARG: ; exit (EXIT_FAILURE); } - ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't map %s: %s\n", cmdname, imagefile, strerror(errno)); @@ -402,7 +404,7 @@ NXTARG: ; hdr->ih_type = opt_type; hdr->ih_comp = opt_comp; - strncpy(hdr->ih_name, name, IH_NMLEN); + strncpy((char *)hdr->ih_name, name, IH_NMLEN); checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); @@ -416,7 +418,7 @@ NXTARG: ; print_header (hdr); - (void) munmap(ptr, sbuf.st_size); + (void) munmap((void *)ptr, sbuf.st_size); exit (EXIT_SUCCESS); } @@ -446,7 +448,8 @@ copy_file (int ifd, const char *datafile, int pad) exit (EXIT_FAILURE); } - ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, dfd, 0); + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, dfd, 0); if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't read %s: %s\n", cmdname, datafile, strerror(errno)); @@ -468,7 +471,7 @@ copy_file (int ifd, const char *datafile, int pad) } } - (void) munmap(ptr, sbuf.st_size); + (void) munmap((void *)ptr, sbuf.st_size); (void) close (dfd); } diff --git a/tqm8xx/ppcboot.lds b/tqm8xx/ppcboot.lds index b80b097..1aad403 100644 --- a/tqm8xx/ppcboot.lds +++ b/tqm8xx/ppcboot.lds @@ -82,7 +82,7 @@ SECTIONS .dtors : { *(.dtors) } /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; + . = (. + 0x00FF) & 0xFFFFFF00; _erotext = .; PROVIDE (erotext = .); .reloc : @@ -112,11 +112,11 @@ SECTIONS __ex_table : { *(__ex_table) } __stop___ex_table = .; - . = ALIGN(4096); + . = ALIGN(256); __init_begin = .; .text.init : { *(.text.init) } .data.init : { *(.data.init) } - . = ALIGN(4096); + . = ALIGN(256); __init_end = .; __bss_start = .;