URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/branches/oc/orpmon
- from Rev 809 to Rev 1765
- ↔ Reverse comparison
Rev 809 → Rev 1765
/include/uart.h
0,0 → 1,142
extern void uart_init(void); |
extern void uart_putc(char); |
extern char uart_getc(void); |
extern char uart_testc(void); |
extern void uart_print_str(char *); |
extern void uart_print_long(unsigned long); |
|
#if 1 |
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ |
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ |
#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ |
#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ |
#define UART_IER 1 /* Out: Interrupt Enable Register */ |
#define UART_IIR 2 /* In: Interrupt ID Register */ |
#define UART_FCR 2 /* Out: FIFO Control Register */ |
#define UART_EFR 2 /* I/O: Extended Features Register */ |
/* (DLAB=1, 16C660 only) */ |
#define UART_LCR 3 /* Out: Line Control Register */ |
#define UART_MCR 4 /* Out: Modem Control Register */ |
#define UART_LSR 5 /* In: Line Status Register */ |
#define UART_MSR 6 /* In: Modem Status Register */ |
#define UART_SCR 7 /* I/O: Scratch Register */ |
#else |
|
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ |
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ |
#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ |
#define UART_DLM 4 /* Out: Divisor Latch High (DLAB=1) */ |
#define UART_IER 4 /* Out: Interrupt Enable Register */ |
#define UART_IIR 8 /* In: Interrupt ID Register */ |
#define UART_FCR 8 /* Out: FIFO Control Register */ |
#define UART_EFR 8 /* I/O: Extended Features Register */ |
/* (DLAB=1, 16C660 only) */ |
#define UART_LCR 12 /* Out: Line Control Register */ |
#define UART_MCR 12 /* Out: Modem Control Register */ |
#define UART_LSR 20 /* In: Line Status Register */ |
#define UART_MSR 24 /* In: Modem Status Register */ |
#define UART_SCR 28 /* I/O: Scratch Register */ |
#endif |
|
/* |
* These are the definitions for the FIFO Control Register |
* (16650 only) |
*/ |
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ |
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ |
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ |
#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ |
#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ |
#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ |
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ |
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ |
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ |
/* 16650 redefinitions */ |
#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */ |
#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */ |
#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */ |
#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */ |
#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */ |
#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ |
#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ |
#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ |
|
/* |
* These are the definitions for the Line Control Register |
* |
* Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting |
* UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. |
*/ |
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ |
#define UART_LCR_SBC 0x40 /* Set break control */ |
#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ |
#define UART_LCR_EPAR 0x10 /* Even parity select */ |
#define UART_LCR_PARITY 0x08 /* Parity Enable */ |
#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 stop bit, 1= 2 stop bits */ |
#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ |
#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ |
#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ |
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ |
|
/* |
* These are the definitions for the Line Status Register |
*/ |
#define UART_LSR_TEMT 0x40 /* Transmitter empty */ |
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ |
#define UART_LSR_BI 0x10 /* Break interrupt indicator */ |
#define UART_LSR_FE 0x08 /* Frame error indicator */ |
#define UART_LSR_PE 0x04 /* Parity error indicator */ |
#define UART_LSR_OE 0x02 /* Overrun error indicator */ |
#define UART_LSR_DR 0x01 /* Receiver data ready */ |
|
/* |
* These are the definitions for the Interrupt Identification Register |
*/ |
#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ |
#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */ |
|
#define UART_IIR_MSI 0x00 /* Modem status interrupt */ |
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */ |
#define UART_IIR_TOI 0x0c /* Receive time out interrupt */ |
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ |
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ |
|
/* |
* These are the definitions for the Interrupt Enable Register |
*/ |
#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ |
#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ |
#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ |
#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ |
|
/* |
* These are the definitions for the Modem Control Register |
*/ |
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ |
#define UART_MCR_OUT2 0x08 /* Out2 complement */ |
#define UART_MCR_OUT1 0x04 /* Out1 complement */ |
#define UART_MCR_RTS 0x02 /* RTS complement */ |
#define UART_MCR_DTR 0x01 /* DTR complement */ |
|
/* |
* These are the definitions for the Modem Status Register |
*/ |
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ |
#define UART_MSR_RI 0x40 /* Ring Indicator */ |
#define UART_MSR_DSR 0x20 /* Data Set Ready */ |
#define UART_MSR_CTS 0x10 /* Clear to Send */ |
#define UART_MSR_DDCD 0x08 /* Delta DCD */ |
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ |
#define UART_MSR_DDSR 0x02 /* Delta DSR */ |
#define UART_MSR_DCTS 0x01 /* Delta CTS */ |
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ |
|
/* |
* These are the definitions for the Extended Features Register |
* (StarTech 16C660 only, when DLAB=1) |
*/ |
#define UART_EFR_CTS 0x80 /* CTS flow control */ |
#define UART_EFR_RTS 0x40 /* RTS flow control */ |
#define UART_EFR_SCD 0x20 /* Special character detect */ |
#define UART_EFR_ENI 0x10 /* Enhanced Interrupt */ |
|
/include/support.h
0,0 → 1,51
/* Support file for or32 tests. This file should is included |
in each test. It calls main() function and add support for |
basic functions */ |
|
#ifndef SUPPORT_H |
#define SUPPORT_H |
|
#include <stdarg.h> |
#include <stddef.h> |
#include <limits.h> |
//#include <_ansi.h> |
|
/* Register access macros */ |
#define REG8(add) *((volatile unsigned char *)(add)) |
#define REG16(add) *((volatile unsigned short *)(add)) |
#define REG32(add) *((volatile unsigned long *)(add)) |
|
|
/* For writing into SPR. */ |
void mtspr(unsigned long spr, unsigned long value); |
|
/* For reading SPR. */ |
unsigned long mfspr(unsigned long spr); |
|
/* Function to be called at entry point - not defined here. */ |
int main (int, char **); |
|
/* Prints out a value */ |
void report(unsigned long value); |
|
/* return value by making a syscall */ |
extern void exit (int i) __attribute__ ((__noreturn__)); |
|
/* memcpy clone */ |
extern void *memcpy (void *__restrict __dest, |
__const void *__restrict __src, size_t __n); |
int memcmp (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length); |
extern void *memchr (void *__restrict dstvoid, |
__const char data, size_t length); |
|
extern int strlen (__const char *srcvoid); |
extern int strcmp (const char *s1, const char *s2); |
extern char *strcpy (char *dst0, char *src0); |
|
extern unsigned long timestamp; |
extern void reset_timer (void); |
extern unsigned long get_timer (unsigned long base); |
extern void set_timer (unsigned long t); |
|
#endif |
/include/screen.h
0,0 → 1,35
#ifndef SCREEN_H |
#define SCREEN_H |
|
#if CRT_ENABLED |
#define RESX 640 |
#define RESY 480 |
#define CHAR_WIDTH 8 |
#define CHAR_HEIGHT 12 |
#define COLOR_BLACK 0x00 |
#define COLOR_WHITE 0xFF |
|
#define CHARSX (RESX/CHAR_WIDTH) |
#define CHARSY (RESY/CHAR_HEIGHT) |
|
#define CRT_REG (CRT_BASE_ADD + 0) |
#define CRT_PALLETE (CRT_BASE_ADD + 0x400) |
#define CRT_BUFFER_REG (CRT_BASE_ADD + 4) |
#define PUT_PIXEL(x, y, color) (*(((unsigned char *)FB_BASE_ADD) + (y) * RESY + (x)) = (color)) |
#define SET_PALLETE(i, r, g, b) (*(((unsigned long *)CRT_PALLETE) + (i) * 4) = ((r) << 4) | ((g) << 8) | ((b) << 12)) |
|
void put_char_xy (int x, int y, char c); |
void put_char (char c); |
void put_string (char *s); |
void screen_clear (void); |
void screen_init (void); |
void screen_putc (char); |
|
extern unsigned long fg_color; |
extern unsigned long bg_color; |
extern int cx; |
extern int cy; |
|
#endif /* CRT_ENABLED */ |
#endif |
|
/include/eth.h
0,0 → 1,148
#define ETH_REG_BASE ETH_BASE |
#define ETH_BD_BASE ETH_BASE + 0x400 |
#define ETH_TOTAL_BD 128 |
#define ETH_MAXBUF_LEN 0x600 |
|
#define ETH_TXBD_NUM 8 |
#define ETH_TXBD_NUM_MASK (ETH_TXBD_NUM - 1) |
#define ETH_RXBD_NUM 8 |
#define ETH_RXBD_NUM_MASK (ETH_RXBD_NUM - 1) |
|
/* Ethernet buffer descriptor */ |
typedef struct _eth_bd { |
unsigned short len; /* Buffer length */ |
unsigned short status; /* Buffer status */ |
unsigned long addr; /* Buffer address */ |
} eth_bd; |
|
extern void eth_init (void (*rec)(volatile unsigned char *, int)); |
extern void *eth_get_tx_buf (void); |
extern void eth_send (void *buf, unsigned long len); |
extern unsigned long eth_rx (void); |
extern void eth_halt(void); |
|
/* Tx BD */ |
#define ETH_TX_BD_READY 0x8000 /* Tx BD Ready */ |
#define ETH_TX_BD_IRQ 0x4000 /* Tx BD IRQ Enable */ |
#define ETH_TX_BD_WRAP 0x2000 /* Tx BD Wrap (last BD) */ |
#define ETH_TX_BD_PAD 0x1000 /* Tx BD Pad Enable */ |
#define ETH_TX_BD_CRC 0x0800 /* Tx BD CRC Enable */ |
|
#define ETH_TX_BD_UNDERRUN 0x0100 /* Tx BD Underrun Status */ |
#define ETH_TX_BD_RETRY 0x00F0 /* Tx BD Retry Status */ |
#define ETH_TX_BD_RETLIM 0x0008 /* Tx BD Retransmission Limit Status */ |
#define ETH_TX_BD_LATECOL 0x0004 /* Tx BD Late Collision Status */ |
#define ETH_TX_BD_DEFER 0x0002 /* Tx BD Defer Status */ |
#define ETH_TX_BD_CARRIER 0x0001 /* Tx BD Carrier Sense Lost Status */ |
#define ETH_TX_BD_STATS (ETH_TX_BD_UNDERRUN | \ |
ETH_TX_BD_RETRY | \ |
ETH_TX_BD_RETLIM | \ |
ETH_TX_BD_LATECOL | \ |
ETH_TX_BD_DEFER | \ |
ETH_TX_BD_CARRIER) |
|
/* Rx BD */ |
#define ETH_RX_BD_EMPTY 0x8000 /* Rx BD Empty */ |
#define ETH_RX_BD_IRQ 0x4000 /* Rx BD IRQ Enable */ |
#define ETH_RX_BD_WRAP 0x2000 /* Rx BD Wrap (last BD) */ |
|
#define ETH_RX_BD_MISS 0x0080 /* Rx BD Miss Status */ |
#define ETH_RX_BD_OVERRUN 0x0040 /* Rx BD Overrun Status */ |
#define ETH_RX_BD_INVSIMB 0x0020 /* Rx BD Invalid Symbol Status */ |
#define ETH_RX_BD_DRIBBLE 0x0010 /* Rx BD Dribble Nibble Status */ |
#define ETH_RX_BD_TOOLONG 0x0008 /* Rx BD Too Long Status */ |
#define ETH_RX_BD_SHORT 0x0004 /* Rx BD Too Short Frame Status */ |
#define ETH_RX_BD_CRCERR 0x0002 /* Rx BD CRC Error Status */ |
#define ETH_RX_BD_LATECOL 0x0001 /* Rx BD Late Collision Status */ |
#define ETH_RX_BD_STATS (ETH_RX_BD_MISS | \ |
ETH_RX_BD_OVERRUN | \ |
ETH_RX_BD_INVSIMB | \ |
ETH_RX_BD_DRIBBLE | \ |
ETH_RX_BD_TOOLONG | \ |
ETH_RX_BD_SHORT | \ |
ETH_RX_BD_CRCERR | \ |
ETH_RX_BD_LATECOL) |
|
/* Register space */ |
#define ETH_MODER 0x00 /* Mode Register */ |
#define ETH_INT 0x04 /* Interrupt Source Register */ |
#define ETH_INT_MASK 0x08 /* Interrupt Mask Register */ |
#define ETH_IPGT 0x0C /* Back to Bak Inter Packet Gap Register */ |
#define ETH_IPGR1 0x10 /* Non Back to Back Inter Packet Gap Register 1 */ |
#define ETH_IPGR2 0x14 /* Non Back to Back Inter Packet Gap Register 2 */ |
#define ETH_PACKETLEN 0x18 /* Packet Length Register (min. and max.) */ |
#define ETH_COLLCONF 0x1C /* Collision and Retry Configuration Register */ |
#define ETH_TX_BD_NUM 0x20 /* Transmit Buffer Descriptor Number Register */ |
#define ETH_CTRLMODER 0x24 /* Control Module Mode Register */ |
#define ETH_MIIMODER 0x28 /* MII Mode Register */ |
#define ETH_MIICOMMAND 0x2C /* MII Command Register */ |
#define ETH_MIIADDRESS 0x30 /* MII Address Register */ |
#define ETH_MIITX_DATA 0x34 /* MII Transmit Data Register */ |
#define ETH_MIIRX_DATA 0x38 /* MII Receive Data Register */ |
#define ETH_MIISTATUS 0x3C /* MII Status Register */ |
#define ETH_MAC_ADDR0 0x40 /* MAC Individual Address Register 0 */ |
#define ETH_MAC_ADDR1 0x44 /* MAC Individual Address Register 1 */ |
#define ETH_HASH_ADDR0 0x48 /* Hash Register 0 */ |
#define ETH_HASH_ADDR1 0x4C /* Hash Register 1 */ |
|
/* MODER Register */ |
#define ETH_MODER_RXEN 0x00000001 /* Receive Enable */ |
#define ETH_MODER_TXEN 0x00000002 /* Transmit Enable */ |
#define ETH_MODER_NOPRE 0x00000004 /* No Preamble */ |
#define ETH_MODER_BRO 0x00000008 /* Reject Broadcast */ |
#define ETH_MODER_IAM 0x00000010 /* Use Individual Hash */ |
#define ETH_MODER_PRO 0x00000020 /* Promiscuous (receive all) */ |
#define ETH_MODER_IFG 0x00000040 /* Min. IFG not required */ |
#define ETH_MODER_LOOPBCK 0x00000080 /* Loop Back */ |
#define ETH_MODER_NOBCKOF 0x00000100 /* No Backoff */ |
#define ETH_MODER_EXDFREN 0x00000200 /* Excess Defer */ |
#define ETH_MODER_FULLD 0x00000400 /* Full Duplex */ |
#define ETH_MODER_RST 0x00000800 /* Reset MAC */ |
#define ETH_MODER_DLYCRCEN 0x00001000 /* Delayed CRC Enable */ |
#define ETH_MODER_CRCEN 0x00002000 /* CRC Enable */ |
#define ETH_MODER_HUGEN 0x00004000 /* Huge Enable */ |
#define ETH_MODER_PAD 0x00008000 /* Pad Enable */ |
#define ETH_MODER_RECSMALL 0x00010000 /* Receive Small */ |
|
/* Interrupt Source Register */ |
#define ETH_INT_TXB 0x00000001 /* Transmit Buffer IRQ */ |
#define ETH_INT_TXE 0x00000002 /* Transmit Error IRQ */ |
#define ETH_INT_RXF 0x00000004 /* Receive Frame IRQ */ |
#define ETH_INT_RXE 0x00000008 /* Receive Error IRQ */ |
#define ETH_INT_BUSY 0x00000010 /* Busy IRQ */ |
#define ETH_INT_TXC 0x00000020 /* Transmit Control Frame IRQ */ |
#define ETH_INT_RXC 0x00000040 /* Received Control Frame IRQ */ |
|
/* Interrupt Mask Register */ |
#define ETH_INT_MASK_TXB 0x00000001 /* Transmit Buffer IRQ Mask */ |
#define ETH_INT_MASK_TXE 0x00000002 /* Transmit Error IRQ Mask */ |
#define ETH_INT_MASK_RXF 0x00000004 /* Receive Frame IRQ Mask */ |
#define ETH_INT_MASK_RXE 0x00000008 /* Receive Error IRQ Mask */ |
#define ETH_INT_MASK_BUSY 0x00000010 /* Busy IRQ Mask */ |
#define ETH_INT_MASK_TXC 0x00000020 /* Transmit Control Frame IRQ Mask */ |
#define ETH_INT_MASK_RXC 0x00000040 /* Received Control Frame IRQ Mask */ |
|
/* Control Module Mode Register */ |
#define ETH_CTRLMODER_PASSALL 0x00000001 /* Pass Control Frames */ |
#define ETH_CTRLMODER_RXFLOW 0x00000002 /* Receive Control Flow Enable */ |
#define ETH_CTRLMODER_TXFLOW 0x00000004 /* Transmit Control Flow Enable */ |
|
/* MII Mode Register */ |
#define ETH_MIIMODER_CLKDIV 0x000000FF /* Clock Divider */ |
#define ETH_MIIMODER_NOPRE 0x00000100 /* No Preamble */ |
#define ETH_MIIMODER_RST 0x00000200 /* MIIM Reset */ |
|
/* MII Command Register */ |
#define ETH_MIICOMMAND_SCANSTAT 0x00000001 /* Scan Status */ |
#define ETH_MIICOMMAND_RSTAT 0x00000002 /* Read Status */ |
#define ETH_MIICOMMAND_WCTRLDATA 0x00000004 /* Write Control Data */ |
|
/* MII Address Register */ |
#define ETH_MIIADDRESS_FIAD 0x0000001F /* PHY Address */ |
#define ETH_MIIADDRESS_RGAD 0x00001F00 /* RGAD Address */ |
|
/* MII Status Register */ |
#define ETH_MIISTATUS_LINKFAIL 0x00000001 /* Link Fail */ |
#define ETH_MIISTATUS_BUSY 0x00000002 /* MII Busy */ |
#define ETH_MIISTATUS_NVALID 0x00000004 /* Data in MII Status Register is invalid */ |
|
/include/spr_defs.h
0,0 → 1,429
/* spr_defs.h -- Defines OR1K architecture specific special-purpose registers |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
/* This file is also used by microkernel test bench. Among |
others it is also used in assembly file(s). */ |
|
/* Definition of special-purpose registers (SPRs) */ |
|
#define MAX_GRPS (32) |
#define MAX_SPRS_PER_GRP_BITS (11) |
#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) |
#define MAX_SPRS (0x10000) |
|
/* Base addresses for the groups */ |
#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) |
#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) |
|
/* System control and status group */ |
#define SPR_VR (SPRGROUP_SYS + 0) |
#define SPR_UPR (SPRGROUP_SYS + 1) |
#define SPR_CPUCFGR (SPRGROUP_SYS + 2) |
#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) |
#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) |
#define SPR_DCCFGR (SPRGROUP_SYS + 5) |
#define SPR_ICCFGR (SPRGROUP_SYS + 6) |
#define SPR_DCFGR (SPRGROUP_SYS + 7) |
#define SPR_PCCFGR (SPRGROUP_SYS + 8) |
#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ |
#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ |
#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ |
#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ |
#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ |
#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) |
#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) |
#define SPR_ESR_BASE (SPRGROUP_SYS + 64) |
#define SPR_ESR_LAST (SPRGROUP_SYS + 79) |
|
/* Data MMU group */ |
#define SPR_DMMUCR (SPRGROUP_DMMU + 0) |
#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100) |
#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100) |
#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100) |
#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100) |
|
/* Instruction MMU group */ |
#define SPR_IMMUCR (SPRGROUP_IMMU + 0) |
#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100) |
#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100) |
#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100) |
#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100) |
|
/* Data cache group */ |
#define SPR_DCCR (SPRGROUP_DC + 0) |
#define SPR_DCBPR (SPRGROUP_DC + 1) |
#define SPR_DCBFR (SPRGROUP_DC + 2) |
#define SPR_DCBIR (SPRGROUP_DC + 3) |
#define SPR_DCBWR (SPRGROUP_DC + 4) |
#define SPR_DCBLR (SPRGROUP_DC + 5) |
#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) |
#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) |
|
/* Instruction cache group */ |
#define SPR_ICCR (SPRGROUP_IC + 0) |
#define SPR_ICBPR (SPRGROUP_IC + 1) |
#define SPR_ICBIR (SPRGROUP_IC + 2) |
#define SPR_ICBLR (SPRGROUP_IC + 3) |
#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) |
#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) |
|
/* MAC group */ |
#define SPR_MACLO (SPRGROUP_MAC + 1) |
#define SPR_MACHI (SPRGROUP_MAC + 2) |
|
/* Debug group */ |
#define SPR_DVR(N) (SPRGROUP_D + (N)) |
#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) |
#define SPR_DMR1 (SPRGROUP_D + 16) |
#define SPR_DMR2 (SPRGROUP_D + 17) |
#define SPR_DWCR0 (SPRGROUP_D + 18) |
#define SPR_DWCR1 (SPRGROUP_D + 19) |
#define SPR_DSR (SPRGROUP_D + 20) |
#define SPR_DRR (SPRGROUP_D + 21) |
|
/* Performance counters group */ |
#define SPR_PCCR(N) (SPRGROUP_PC + (N)) |
#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) |
|
/* Power management group */ |
#define SPR_PMR (SPRGROUP_PM + 0) |
|
/* PIC group */ |
#define SPR_PICMR (SPRGROUP_PIC + 0) |
#define SPR_PICPR (SPRGROUP_PIC + 1) |
#define SPR_PICSR (SPRGROUP_PIC + 2) |
|
/* Tick Timer group */ |
#define SPR_TTMR (SPRGROUP_TT + 0) |
#define SPR_TTCR (SPRGROUP_TT + 1) |
|
/* |
* Bit definitions for the Version Register |
* |
*/ |
#define SPR_VR_VER 0xffff0000 /* Processor version */ |
#define SPR_VR_REV 0x0000003f /* Processor revision */ |
|
/* |
* Bit definitions for the Unit Present Register |
* |
*/ |
#define SPR_UPR_UP 0x00000001 /* UPR present */ |
#define SPR_UPR_DCP 0x00000002 /* Data cache present */ |
#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ |
#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ |
#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ |
#define SPR_UPR_OB32P 0x00000020 /* ORBIS32 present */ |
#define SPR_UPR_OB64P 0x00000040 /* ORBIS64 present */ |
#define SPR_UPR_OF32P 0x00000080 /* ORFPX32 present */ |
#define SPR_UPR_OF64P 0x00000100 /* ORFPX64 present */ |
#define SPR_UPR_OV32P 0x00000200 /* ORVDX32 present */ |
#define SPR_UPR_OV64P 0x00000400 /* ORVDX64 present */ |
#define SPR_UPR_DUP 0x00000800 /* Debug unit present */ |
#define SPR_UPR_PCUP 0x00001000 /* Performance counters unit present */ |
#define SPR_UPR_PMP 0x00002000 /* Power management present */ |
#define SPR_UPR_PICP 0x00004000 /* PIC present */ |
#define SPR_UPR_TTP 0x00008000 /* Tick timer present */ |
#define SPR_UPR_SRP 0x00010000 /* Shadow registers present */ |
#define SPR_UPR_RES 0x00fe0000 /* ORVDX32 present */ |
#define SPR_UPR_CUST 0xff000000 /* Custom units */ |
|
/* |
* Bit definitions for the Supervision Register |
* |
*/ |
#define SPR_SR_CID 0xf0000000 /* Context ID */ |
#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */ |
#define SPR_SR_FO 0x00008000 /* Fixed one */ |
#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */ |
#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ |
#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ |
#define SPR_SR_OV 0x00000800 /* Overflow flag */ |
#define SPR_SR_CY 0x00000400 /* Carry flag */ |
#define SPR_SR_F 0x00000200 /* Condition Flag */ |
#define SPR_SR_CE 0x00000100 /* CID Enable */ |
#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ |
#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ |
#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ |
#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ |
#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ |
#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ |
#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ |
#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ |
|
/* |
* Bit definitions for the Data MMU Control Register |
* |
*/ |
#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ |
#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ |
#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ |
#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ |
|
/* |
* Bit definitions for the Instruction MMU Control Register |
* |
*/ |
#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ |
#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ |
#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ |
#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ |
|
/* |
* Bit definitions for the Data TLB Match Register |
* |
*/ |
#define SPR_DTLBMR_V 0x00000001 /* Valid */ |
#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ |
#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ |
#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ |
#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */ |
|
/* |
* Bit definitions for the Data TLB Translate Register |
* |
*/ |
#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ |
#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ |
#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ |
#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ |
#define SPR_DTLBTR_A 0x00000010 /* Accessed */ |
#define SPR_DTLBTR_D 0x00000020 /* Dirty */ |
#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ |
#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ |
#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ |
#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ |
#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */ |
|
/* |
* Bit definitions for the Instruction TLB Match Register |
* |
*/ |
#define SPR_ITLBMR_V 0x00000001 /* Valid */ |
#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ |
#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ |
#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ |
#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */ |
|
/* |
* Bit definitions for the Instruction TLB Translate Register |
* |
*/ |
#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ |
#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ |
#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ |
#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ |
#define SPR_ITLBTR_A 0x00000010 /* Accessed */ |
#define SPR_ITLBTR_D 0x00000020 /* Dirty */ |
#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ |
#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ |
#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */ |
|
/* |
* Bit definitions for Data Cache Control register |
* |
*/ |
#define SPR_DCCR_EW 0x000000ff /* Enable ways */ |
|
/* |
* Bit definitions for Insn Cache Control register |
* |
*/ |
#define SPR_ICCR_EW 0x000000ff /* Enable ways */ |
|
/* |
* Bit definitions for Debug Control registers |
* |
*/ |
#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ |
#define SPR_DCR_CC 0x0000000e /* Compare condition */ |
#define SPR_DCR_SC 0x00000010 /* Signed compare */ |
#define SPR_DCR_CT 0x000000e0 /* Compare to */ |
|
/* Bit results with SPR_DCR_CC mask */ |
#define SPR_DCR_CC_MASKED 0x00000000 |
#define SPR_DCR_CC_EQUAL 0x00000001 |
#define SPR_DCR_CC_LESS 0x00000002 |
#define SPR_DCR_CC_LESSE 0x00000003 |
#define SPR_DCR_CC_GREAT 0x00000004 |
#define SPR_DCR_CC_GREATE 0x00000005 |
#define SPR_DCR_CC_NEQUAL 0x00000006 |
|
/* Bit results with SPR_DCR_CT mask */ |
#define SPR_DCR_CT_DISABLED 0x00000000 |
#define SPR_DCR_CT_IFEA 0x00000020 |
#define SPR_DCR_CT_LEA 0x00000040 |
#define SPR_DCR_CT_SEA 0x00000060 |
#define SPR_DCR_CT_LD 0x00000080 |
#define SPR_DCR_CT_SD 0x000000a0 |
#define SPR_DCR_CT_LSEA 0x000000c0 |
|
/* |
* Bit definitions for Debug Mode 1 register |
* |
*/ |
#define SPR_DMR1_CW0 0x00000003 /* Chain watchpoint 0 */ |
#define SPR_DMR1_CW1 0x0000000c /* Chain watchpoint 1 */ |
#define SPR_DMR1_CW2 0x00000030 /* Chain watchpoint 2 */ |
#define SPR_DMR1_CW3 0x000000c0 /* Chain watchpoint 3 */ |
#define SPR_DMR1_CW4 0x00000300 /* Chain watchpoint 4 */ |
#define SPR_DMR1_CW5 0x00000c00 /* Chain watchpoint 5 */ |
#define SPR_DMR1_CW6 0x00003000 /* Chain watchpoint 6 */ |
#define SPR_DMR1_CW7 0x0000c000 /* Chain watchpoint 7 */ |
#define SPR_DMR1_CW8 0x00030000 /* Chain watchpoint 8 */ |
#define SPR_DMR1_CW9 0x000c0000 /* Chain watchpoint 9 */ |
#define SPR_DMR1_CW10 0x00300000 /* Chain watchpoint 10 */ |
#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ |
#define SPR_DMR1_BT 0x00800000 /* Branch trace */ |
#define SPR_DMR1_DXFW 0x01000000 /* Disable external force watchpoint */ |
|
/* |
* Bit definitions for Debug Mode 2 register |
* |
*/ |
#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ |
#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ |
#define SPR_DMR2_AWTC 0x00001ffc /* Assign watchpoints to counters */ |
#define SPR_DMR2_WGB 0x00ffe000 /* Watchpoints generating breakpoint */ |
|
/* |
* Bit definitions for Debug watchpoint counter registers |
* |
*/ |
#define SPR_DWCR_COUNT 0x0000ffff /* Count */ |
#define SPR_DWCR_MATCH 0xffff0000 /* Match */ |
|
/* |
* Bit definitions for Debug stop register |
* |
*/ |
#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ |
#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ |
#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ |
#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ |
#define SPR_DSR_TTE 0x00000010 /* iTick Timer exception */ |
#define SPR_DSR_AE 0x00000020 /* Alignment exception */ |
#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ |
#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ |
#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ |
#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ |
#define SPR_DSR_RE 0x00000400 /* Range exception */ |
#define SPR_DSR_SCE 0x00000800 /* System call exception */ |
#define SPR_DSR_SSE 0x00001000 /* Single Step Exception */ |
#define SPR_DSR_TE 0x00002000 /* Trap exception */ |
|
/* |
* Bit definitions for Debug reason register |
* |
*/ |
#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ |
#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ |
#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ |
#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ |
#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ |
#define SPR_DRR_AE 0x00000020 /* Alignment exception */ |
#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ |
#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ |
#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ |
#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ |
#define SPR_DRR_RE 0x00000400 /* Range exception */ |
#define SPR_DRR_SCE 0x00000800 /* System call exception */ |
#define SPR_DRR_TE 0x00001000 /* Trap exception */ |
|
/* |
* Bit definitions for Performance counters mode registers |
* |
*/ |
#define SPR_PCMR_CP 0x00000001 /* Counter present */ |
#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ |
#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ |
#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ |
#define SPR_PCMR_LA 0x00000010 /* Load access event */ |
#define SPR_PCMR_SA 0x00000020 /* Store access event */ |
#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ |
#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ |
#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ |
#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ |
#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ |
#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ |
#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ |
#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ |
#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ |
#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ |
|
/* |
* Bit definitions for the Power management register |
* |
*/ |
#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ |
#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ |
#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ |
#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ |
#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ |
|
/* |
* Bit definitions for PICMR |
* |
*/ |
#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ |
|
/* |
* Bit definitions for PICPR |
* |
*/ |
#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ |
|
/* |
* Bit definitions for PICSR |
* |
*/ |
#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ |
|
/* |
* Bit definitions for Tick Timer Control Register |
* |
*/ |
#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ |
#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD |
#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ |
#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ |
#define SPR_TTMR_RT 0x40000000 /* Restart tick */ |
#define SPR_TTMR_SR 0x80000000 /* Single run */ |
#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ |
#define SPR_TTMR_M 0xc0000000 /* Tick mode */ |
|
/* |
* l.nop constants |
* |
*/ |
#define NOP_NOP 0x0000 /* Normal nop instruction */ |
#define NOP_EXIT 0x0001 /* End of simulation */ |
#define NOP_REPORT 0x0002 /* Simple report */ |
#define NOP_PRINTF 0x0003 /* Simprintf instruction */ |
#define NOP_REPORT_FIRST 0x0400 /* Report with number */ |
#define NOP_REPORT_LAST 0x03ff /* Report with number */ |
/include/net.h
0,0 → 1,306
/* |
* LiMon Monitor (LiMon) - Network. |
* |
* Copyright 1994 - 2000 Neil Russell. |
* (See License) |
* |
* |
* History |
* 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added |
*/ |
|
#ifndef __NET_H__ |
#define __NET_H__ |
|
|
/* |
* The number of receive packet buffers, and the required packet buffer |
* alignment in memory. |
* |
*/ |
|
#define PKTBUFSRX 4 |
#define PKTALIGN 32 |
|
/****** from cpu_arch.h ************/ |
|
/* Byte swapping stuff (not needed on PPC). */ |
|
#define SWAP16(x) (x) |
#define SWAP16c(x) (x) |
#define SWAP32(x) (x) |
|
/****** end from cpu_arch.h **************/ |
|
typedef unsigned long IPaddr_t; |
|
|
|
/* |
* The current receive packet handler. Called with a pointer to the |
* application packet, and a protocol type (PORT_BOOTPC or PORT_TFTP). |
* All other packets are dealt with without calling the handler. |
*/ |
typedef void rxhand_f(unsigned char *, unsigned, unsigned, unsigned); |
|
/* |
* A timeout handler. Called after time interval has expired. |
*/ |
typedef void thand_f(void); |
|
#ifdef CONFIG_NET_MULTI |
|
#define NAMESIZE 16 |
|
enum eth_state_t { |
ETH_STATE_INIT, |
ETH_STATE_PASSIVE, |
ETH_STATE_ACTIVE |
}; |
|
struct eth_device { |
char name[NAMESIZE]; |
unsigned char enetaddr[6]; |
int iobase; |
int state; |
|
int (*init) (struct eth_device*, bd_t*); |
int (*send) (struct eth_device*, volatile void* pachet, int length); |
int (*recv) (struct eth_device*); |
void (*halt) (struct eth_device*); |
|
struct eth_device *next; |
void *priv; |
}; |
|
extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */ |
extern int eth_register(struct eth_device* dev);/* Register network device */ |
extern void eth_try_another(void); /* Change the device */ |
#endif |
|
/**********************************************************************/ |
/* |
* Protocol headers. |
*/ |
|
/* |
* Ethernet header |
*/ |
typedef struct { |
unsigned char et_dest[6]; /* Destination node */ |
unsigned char et_src[6]; /* Source node */ |
unsigned short et_protlen; /* Protocol or length */ |
unsigned char et_dsap; /* 802 DSAP */ |
unsigned char et_ssap; /* 802 SSAP */ |
unsigned char et_ctl; /* 802 control */ |
unsigned char et_snap1; /* SNAP */ |
unsigned char et_snap2; |
unsigned char et_snap3; |
unsigned short et_prot; /* 802 protocol */ |
} Ethernet_t; |
|
#define ETHER_HDR_SIZE 14 /* Ethernet header size */ |
#define E802_HDR_SIZE 22 /* 802 ethernet header size */ |
#define PROT_IP 0x0800 /* IP protocol */ |
#define PROT_ARP 0x0806 /* IP ARP protocol */ |
#define PROT_RARP 0x8035 /* IP ARP protocol */ |
|
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ |
#define IPPROTO_UDP 17 /* User Datagram Protocol */ |
|
/* |
* Internet Protocol (IP) header. |
*/ |
typedef struct { |
unsigned char ip_hl_v; /* header length and version */ |
unsigned char ip_tos; /* type of service */ |
unsigned short ip_len; /* total length */ |
unsigned short ip_id; /* identification */ |
unsigned short ip_off; /* fragment offset field */ |
unsigned char ip_ttl; /* time to live */ |
unsigned char ip_p; /* protocol */ |
unsigned short ip_sum; /* checksum */ |
IPaddr_t ip_src; /* Source IP address */ |
IPaddr_t ip_dst; /* Destination IP address */ |
unsigned short udp_src; /* UDP source port */ |
unsigned short udp_dst; /* UDP destination port */ |
unsigned short udp_len; /* Length of UDP packet */ |
unsigned short udp_xsum; /* Checksum */ |
} IP_t; |
|
#define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8) |
#define IP_HDR_SIZE (sizeof (IP_t)) |
|
|
/* |
* Address Resolution Protocol (ARP) header. |
*/ |
typedef struct |
{ |
unsigned short ar_hrd; /* Format of hardware address */ |
# define ARP_ETHER 1 /* Ethernet hardware address */ |
unsigned short ar_pro; /* Format of protocol address */ |
unsigned char ar_hln; /* Length of hardware address */ |
unsigned char ar_pln; /* Length of protocol address */ |
unsigned short ar_op; /* Operation */ |
# define ARPOP_REQUEST 1 /* Request to resolve address */ |
# define ARPOP_REPLY 2 /* Response to previous request */ |
|
# define RARPOP_REQUEST 3 /* Request to resolve address */ |
# define RARPOP_REPLY 4 /* Response to previous request */ |
|
/* |
* The remaining fields are variable in size, according to |
* the sizes above, and are defined as appropriate for |
* specific hardware/protocol combinations. |
*/ |
unsigned char ar_data[0]; |
#if 0 |
unsigned char ar_sha[]; /* Sender hardware address */ |
unsigned char ar_spa[]; /* Sender protocol address */ |
unsigned char ar_tha[]; /* Target hardware address */ |
unsigned char ar_tpa[]; /* Target protocol address */ |
#endif /* 0 */ |
} ARP_t; |
|
#define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */ |
|
/* |
* ICMP stuff (just enough to handle (host) redirect messages) |
*/ |
#define ICMP_REDIRECT 5 /* Redirect (change route) */ |
|
/* Codes for REDIRECT. */ |
#define ICMP_REDIR_NET 0 /* Redirect Net */ |
#define ICMP_REDIR_HOST 1 /* Redirect Host */ |
|
typedef struct icmphdr { |
unsigned char type; |
unsigned char code; |
unsigned short checksum; |
union { |
struct { |
unsigned short id; |
unsigned short sequence; |
} echo; |
unsigned long gateway; |
struct { |
unsigned short __unused; |
unsigned short mtu; |
} frag; |
} un; |
} ICMP_t; |
|
|
|
/* |
* Maximum packet size; used to allocate packet storage. |
* TFTP packets can be 524 bytes + IP header + ethernet header. |
* Lets be conservative, and go for 38 * 16. (Must also be |
* a multiple of 32 bytes). |
*/ |
/* |
* AS.HARNOIS : Better to set PKTSIZE to maximum size because |
* traffic type is not always controlled |
* maximum packet size = 1518 |
* maximum packet size and multiple of 32 bytes = 1536 |
*/ |
#define PKTSIZE 1518 |
#define PKTSIZE_ALIGN 1536 |
/*#define PKTSIZE 608*/ |
|
/* |
* Maximum receive ring size; that is, the number of packets |
* we can buffer before overflow happens. Basically, this just |
* needs to be enough to prevent a packet being discarded while |
* we are processing the previous one. |
*/ |
#define RINGSZ 4 |
#define RINGSZ_LOG2 2 |
|
/**********************************************************************/ |
/* |
* Globals. |
*/ |
|
/* net.c */ |
/** BOOTP EXTENTIONS **/ |
extern IPaddr_t NetOurGatewayIP; /* Our gateway IP addresse */ |
extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown)*/ |
extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown)*/ |
extern char NetOurNISDomain[32]; /* Our NIS domain */ |
extern char NetOurHostName[32]; /* Our hostname */ |
extern char NetOurRootPath[64]; /* Our root path */ |
extern unsigned short NetBootFileSize; /* Our boot file size in blocks */ |
/** END OF BOOTP EXTENTIONS **/ |
extern unsigned long NetBootFileXferSize; /* size of bootfile in bytes */ |
extern unsigned char NetOurEther[6]; /* Our ethernet address */ |
extern unsigned char NetServerEther[6]; /* Boot server enet address */ |
extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ |
extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ |
extern volatile unsigned char * NetTxPacket; /* THE transmit packet */ |
extern volatile unsigned char * NetRxPackets[PKTBUFSRX];/* Receive packets */ |
extern volatile unsigned char * NetRxPkt; /* Current receive packet */ |
extern int NetRxPktLen; /* Current rx packet length */ |
extern unsigned NetIPID; /* IP ID (counting) */ |
extern unsigned char NetBcastAddr[6]; /* Ethernet boardcast address */ |
|
extern int NetState; /* Network loop state */ |
#define NETLOOP_CONTINUE 1 |
#define NETLOOP_RESTART 2 |
#define NETLOOP_SUCCESS 3 |
#define NETLOOP_FAIL 4 |
|
|
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t; |
|
/* from net/net.c */ |
extern char BootFile[128]; /* Boot File name */ |
|
/* Initialize the network adapter */ |
extern int NetLoop(proto_t protocol); |
|
/* Shutdown adapters and cleanup */ |
extern void NetStop(void); |
|
/* Load failed. Start again. */ |
extern void NetStartAgain(void); |
|
/* Copy ethernet address */ |
extern void NetCopyEther(volatile unsigned char *, unsigned char *); |
|
/* Set ethernet header */ |
extern void NetSetEther(volatile unsigned char *, unsigned char *, unsigned long); |
|
/* Set IP header */ |
extern void NetSetIP(volatile unsigned char *, IPaddr_t, int, int, int); |
|
/* Checksum */ |
extern int NetCksumOk(unsigned char *, int); /* Return true if cksum OK */ |
extern unsigned NetCksum(unsigned char *, int); /* Calculate the checksum */ |
|
/* Set callbacks */ |
extern void NetSetHandler(rxhand_f *); /* Set RX packet handler */ |
extern void NetSetTimeout(int, thand_f *); /* Set timeout handler */ |
|
/* Transmit "NetTxPacket" */ |
extern void NetSendPacket(volatile unsigned char *, int); |
|
/* Processes a received packet */ |
extern void NetReceive(volatile unsigned char *, int); |
|
/* Print an IP address on the console */ |
extern void print_IPaddr (IPaddr_t); |
|
/* Convert an IP address to a string */ |
extern void ip_to_string (IPaddr_t x, char *s); |
|
/* read an IP address from a environment variable */ |
extern IPaddr_t getenv_IPaddr (char *); |
|
/* copy a filename (allow for "..." notation, limit length) */ |
extern void copy_filename (unsigned char *dst, unsigned char *src, int size); |
|
/**********************************************************************/ |
|
#endif /* __NET_H__ */ |
/include/board.h
0,0 → 1,67
#ifndef _BOARD_H_ |
#define _BOARD_H_ |
|
#ifdef XESS |
#define MC_ENABLED 0 |
#else |
#define MC_ENABLED 1 |
#endif |
|
#define IC_ENABLE 0 |
#define IC_SIZE 8192 |
#define DC_ENABLE 0 |
#define DC_SIZE 8192 |
|
#define MC_CSR_VAL 0x0B000300 |
#define MC_MASK_VAL 0x000000e0 |
#define FLASH_BASE_ADD 0x04000000 |
#define FLASH_TMS_VAL 0x00102102 |
#define SDRAM_BASE_ADD 0x00000000 |
#define SDRAM_TMS_VAL 0x07248230 |
|
#ifdef XESS |
#define IN_CLK 10000000 |
#else |
#define IN_CLK 25000000 |
#endif |
|
#define STACK_SIZE 0x10000 |
|
#ifdef XESS |
#define UART_BAUD_RATE 19200 |
#else |
#define UART_BAUD_RATE 9600 /* 115200 */ |
#endif |
|
#define UART_BASE 0x90000000 |
#ifdef XESS |
#define ETH_BASE 0x92000000 |
#else |
#define ETH_BASE 0xD0000000 |
#endif |
#define MC_BASE_ADD 0x60000000 |
|
#define ETH0_INT _int_main /* was: 0x00080000 */ /* Not correct */ |
|
/*#define ETH_DATA_BASE 0x00020000 Address for ETH_DATA */ |
#ifdef XESS |
#define ETH_DATA_BASE 0x00100000 /* Address for ETH_DATA */ |
#else |
#define ETH_DATA_BASE 0xa8000000 /* Address for ETH_DATA */ |
#endif |
|
#define ETH_MACADDR0 0x00 |
#define ETH_MACADDR1 0x09 |
#define ETH_MACADDR2 0x12 |
#define ETH_MACADDR3 0x34 |
#define ETH_MACADDR4 0x56 |
#define ETH_MACADDR5 0x00 |
|
#define CRT_ENABLED 1 |
#define CRT_BASE_ADD 0xc0000000 |
#define FB_BASE_ADD 0xa8000000 |
|
/* Whether online help is available -- saves space */ |
#define HELP_ENABLED 1 |
|
#endif |
/include/common.h
0,0 → 1,86
#ifndef _COMMON_H_ |
#define _COMMON_H_ |
|
#include "board.h" |
|
#ifdef DEBUG |
#define debug(fmt,args...) printf (fmt ,##args) |
#else |
#define debug(fmt,args...) __printf (fmt ,##args) |
#endif |
|
/* A Board Information structure that is given to a program when |
* ppcboot starts it up. */ |
typedef struct bd_info { |
enum bi_console_type_t { |
CT_NONE, |
CT_UART, |
CT_CRT, |
CT_SIM, |
} bi_console_type; |
unsigned long bi_memstart; /* start of DRAM memory */ |
unsigned long bi_memsize; /* size of DRAM memory in bytes */ |
unsigned long bi_flashstart; /* start of FLASH memory */ |
unsigned long bi_flashsize; /* size of FLASH memory */ |
unsigned long bi_flashoffset; /* reserved area for startup monitor */ |
unsigned long bi_sramstart; /* start of SRAM memory */ |
unsigned long bi_sramsize; /* size of SRAM memory */ |
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ |
unsigned long bi_ip_addr; /* IP Address */ |
unsigned char bi_enetaddr[6]; /* Ethernet adress */ |
unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ |
unsigned long bi_intfreq; /* Internal Freq, in MHz */ |
unsigned long bi_busfreq; /* Bus Freq, in MHz */ |
unsigned long bi_baudrate; /* Console Baudrate */ |
} bd_t; |
|
typedef struct { |
unsigned long src_addr; |
unsigned long dst_addr; |
unsigned long length; |
unsigned long ip; |
unsigned long gw_ip; |
unsigned long mask; |
unsigned long srv_ip; |
unsigned char eth_add[6]; |
} global_struct; |
|
extern bd_t bd; |
extern global_struct global; |
|
/* stdio */ |
extern int getc (void); |
extern int testc (void); |
extern int ctrlc (void); |
extern void putc (const char c); |
extern int printf (const char *fmt, ...); |
|
extern unsigned long strtoul(char *s); |
|
/* simulator stdout */ |
extern void __printf (const char *fmt, ...); |
|
/* Reports a 32bit value to the simulator */ |
extern void report(unsigned long value); |
|
/* Commands stuff */ |
#if HELP_ENABLED |
#define register_command(name,params,help,funct) register_command_func (name, params, help, funct) |
#else /* !HELP_ENABLED */ |
#define register_command(name,params,help,funct) register_command_func (name, "", "", funct) |
#endif /* HELP_ENABLED */ |
|
extern void register_command_func (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[])); |
|
/* Redirects console */ |
extern void change_console_type (enum bi_console_type_t con_type); |
|
/* OR1k specific */ |
/* For writing into SPR. */ |
extern void mtspr(unsigned long spr, unsigned long value); |
|
/* For reading SPR. */ |
extern unsigned long mfspr(unsigned long spr); |
|
#endif /* _COMMON_H_ */ |
|
/reset.S
0,0 → 1,301
#include "spr_defs.h" |
#include "board.h" |
#include "mc.h" |
|
|
|
.extern _reset_support |
.extern _eth_int |
.extern _src_beg |
.extern _dst_beg |
.extern _dst_end |
.extern _c_reset |
.extern _int_main |
|
.global _lolev_ie |
.global _lolev_idis |
|
.section .stack, "aw", @nobits |
.space STACK_SIZE |
_stack: |
|
.if IN_FLASH |
.section .reset, "ax" |
.else |
.section .vectors, "ax" |
.endif |
|
.org 0x100 |
_reset: |
.if IN_FLASH |
l.movhi r3,hi(MC_BASE_ADD) |
l.ori r3,r3,MC_BA_MASK |
l.addi r5,r0,0x00 |
l.sw 0(r3),r5 |
.endif |
l.movhi r3,hi(_start) |
l.ori r3,r3,lo(_start) |
l.jr r3 |
l.nop |
|
.if IN_FLASH |
.section .vectors, "ax" |
.endif |
.org 0x800 |
|
l.j _int_wrapper |
l.nop |
|
.section .text |
|
_start: |
.if IN_FLASH |
l.jal _init_mc |
l.nop |
|
/* Wait for SDRAM */ |
l.addi r3,r0,0x0000 /* igor zmanjsal iz 0x7fff na 0x0000 */ |
1: l.sfeqi r3,0 |
l.bnf 1b |
l.addi r3,r3,-1 |
.endif |
/* Copy form flash to sram */ |
.if IN_FLASH |
l.movhi r3,hi(_src_beg) |
l.ori r3,r3,lo(_src_beg) |
l.movhi r4,hi(_vec_start) |
l.ori r4,r4,lo(_vec_start) |
l.movhi r5,hi(_vec_end) |
l.ori r5,r5,lo(_vec_end) |
l.sub r5,r5,r4 |
l.sfeqi r5,0 |
l.bf 2f |
l.nop |
1: l.lwz r6,0(r3) |
l.sw 0(r4),r6 |
l.addi r3,r3,4 |
l.addi r4,r4,4 |
l.addi r5,r5,-4 |
l.sfgtsi r5,0 |
l.bf 1b |
l.nop |
2: |
l.movhi r4,hi(_dst_beg) |
l.ori r4,r4,lo(_dst_beg) |
l.movhi r5,hi(_dst_end) |
l.ori r5,r5,lo(_dst_end) |
1: l.sfgeu r4,r5 |
l.bf 1f |
l.nop |
l.lwz r8,0(r3) |
l.sw 0(r4),r8 |
l.addi r3,r3,4 |
l.bnf 1b |
l.addi r4,r4,4 |
1: |
l.addi r3,r0,0 |
l.addi r4,r0,0 |
3: |
.endif |
|
.if IC_ENABLE |
l.jal _ic_enable |
l.nop |
.endif |
|
.if DC_ENABLE |
l.jal _dc_enable |
l.nop |
.endif |
|
l.movhi r1,hi(_stack-4) |
l.addi r1,r1,lo(_stack-4) |
l.addi r2,r0,-3 |
l.and r1,r1,r2 |
|
l.movhi r2,hi(_main) |
l.ori r2,r2,lo(_main) |
l.jr r2 |
l.addi r2,r0,0 |
|
_ic_enable: |
|
/* Flush IC */ |
l.addi r10,r0,0 |
l.addi r11,r0,IC_SIZE |
1: |
l.mtspr r0,r10,SPR_ICBIR |
l.sfne r10,r11 |
l.bf 1b |
l.addi r10,r10,16 |
|
/* Enable IC */ |
l.addi r10,r0,(SPR_SR_ICE|SPR_SR_SM) |
l.mtspr r0,r10,SPR_SR |
l.nop |
l.nop |
l.nop |
l.nop |
l.nop |
|
l.jr r9 |
l.nop |
|
_dc_enable: |
|
/* Flush DC */ |
l.addi r10,r0,0 |
l.addi r11,r0,DC_SIZE |
1: |
l.mtspr r0,r10,SPR_DCBIR |
l.sfne r10,r11 |
l.bf 1b |
l.addi r10,r10,16 |
|
/* Enable DC */ |
l.addi r10,r0,(SPR_SR_DCE|SPR_SR_SM) |
l.mtspr r0,r10,SPR_SR |
|
l.jr r9 |
l.nop |
|
.if IN_FLASH |
_init_mc: |
|
l.movhi r3,hi(MC_BASE_ADD) |
l.ori r3,r3,lo(MC_BASE_ADD) |
|
l.addi r4,r3,MC_CSC(0) |
l.movhi r5,hi(FLASH_BASE_ADD) |
l.srai r5,r5,5 |
l.ori r5,r5,0x0025 |
l.sw 0(r4),r5 |
|
l.addi r4,r3,MC_TMS(0) |
l.movhi r5,hi(FLASH_TMS_VAL) |
l.ori r5,r5,lo(FLASH_TMS_VAL) |
l.sw 0(r4),r5 |
|
l.addi r4,r3,MC_BA_MASK |
l.addi r5,r0,MC_MASK_VAL |
l.sw 0(r4),r5 |
|
l.addi r4,r3,MC_CSR |
l.movhi r5,hi(MC_CSR_VAL) |
l.ori r5,r5,lo(MC_CSR_VAL) |
l.sw 0(r4),r5 |
|
l.addi r4,r3,MC_TMS(1) |
l.movhi r5,hi(SDRAM_TMS_VAL) |
l.ori r5,r5,lo(SDRAM_TMS_VAL) |
l.sw 0(r4),r5 |
|
l.addi r4,r3,MC_CSC(1) |
l.movhi r5,hi(SDRAM_BASE_ADD) |
l.srai r5,r5,5 |
l.ori r5,r5,0x0411 |
l.sw 0(r4),r5 |
|
l.jr r9 |
l.nop |
.endif |
|
_int_wrapper: |
l.addi r1,r1,-128 |
|
l.sw 0x4(r1),r2 |
l.sw 0x8(r1),r4 |
l.sw 0xc(r1),r5 |
l.sw 0x10(r1),r6 |
l.sw 0x14(r1),r7 |
l.sw 0x18(r1),r8 |
l.sw 0x1c(r1),r9 |
l.sw 0x20(r1),r10 |
l.sw 0x24(r1),r11 |
l.sw 0x28(r1),r12 |
l.sw 0x2c(r1),r13 |
l.sw 0x30(r1),r14 |
l.sw 0x34(r1),r15 |
l.sw 0x38(r1),r16 |
l.sw 0x3c(r1),r17 |
l.sw 0x40(r1),r18 |
l.sw 0x44(r1),r19 |
l.sw 0x48(r1),r20 |
l.sw 0x4c(r1),r21 |
l.sw 0x50(r1),r22 |
l.sw 0x54(r1),r23 |
l.sw 0x58(r1),r24 |
l.sw 0x5c(r1),r25 |
l.sw 0x60(r1),r26 |
l.sw 0x64(r1),r27 |
l.sw 0x68(r1),r28 |
l.sw 0x6c(r1),r29 |
l.sw 0x70(r1),r30 |
l.sw 0x74(r1),r31 |
l.sw 0x78(r1),r3 |
|
l.movhi r3,hi(_eth_int) |
l.ori r3,r3,lo(_eth_int) |
l.jalr r3 |
l.nop |
|
l.lwz r2,0x4(r1) |
l.lwz r4,0x8(r1) |
l.lwz r5,0xc(r1) |
l.lwz r6,0x10(r1) |
l.lwz r7,0x14(r1) |
l.lwz r8,0x18(r1) |
l.lwz r9,0x1c(r1) |
l.lwz r10,0x20(r1) |
l.lwz r11,0x24(r1) |
l.lwz r12,0x28(r1) |
l.lwz r13,0x2c(r1) |
l.lwz r14,0x30(r1) |
l.lwz r15,0x34(r1) |
l.lwz r16,0x38(r1) |
l.lwz r17,0x3c(r1) |
l.lwz r18,0x40(r1) |
l.lwz r19,0x44(r1) |
l.lwz r20,0x48(r1) |
l.lwz r21,0x4c(r1) |
l.lwz r22,0x50(r1) |
l.lwz r23,0x54(r1) |
l.lwz r24,0x58(r1) |
l.lwz r25,0x5c(r1) |
l.lwz r26,0x60(r1) |
l.lwz r27,0x64(r1) |
l.lwz r28,0x68(r1) |
l.lwz r29,0x6c(r1) |
l.lwz r30,0x70(r1) |
l.lwz r31,0x74(r1) |
# l.lwz r3,0x78(r1) |
|
l.mtspr r0,r0,SPR_PICSR |
|
l.mfspr r3,r0,SPR_ESR_BASE |
l.ori r3,r3,SPR_SR_IEE |
l.mtspr r0,r3,SPR_ESR_BASE |
|
l.lwz r3,0x78(r1) |
|
l.addi r1,r1,128 |
l.rfe |
l.nop |
|
.section .text |
_lolev_ie: |
l.mfspr r3,r0,SPR_SR |
l.ori r3,r3,SPR_SR_IEE |
l.mtspr r0,r3,SPR_SR |
l.movhi r3,hi(ETH0_INT) |
l.ori r3,r3,lo(ETH0_INT) |
l.mtspr r0,r3,SPR_PICMR |
|
l.jr r9 |
l.nop |
|
_lolev_idis: |
l.mtspr r0,r0,SPR_PICMR |
|
l.jr r9 |
l.nop |
/services/.Makefile.swp
0,0 → 1,10
+ Ï — ƒ € a ` O N # ú ù í ì Ó » º p o O ' & Ê
+ ######################################################################### sinclude .depend $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ .depend: Makefile $(OBJS:.o=.c) ######################################################################### $(LD) -r -o $@ $(OBJS) $(LIB): $(START) $(OBJS) all: $(LIB) OBJS = net.o tftp.o bootp.o rarp.o arp.o # OBJS = net.o tftp.o bootp.o rarp.o arp.o LIB = services.o # CFLAGS += -DET_DEBUG -DDEBUG # # MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, # along with this program; if not, write to the Free Software # You should have received a copy of the GNU General Public License # # GNU General Public License for more details. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # but WITHOUT ANY WARRANTY; without even the implied warranty of # This program is distributed in the hope that it will be useful, # # the License, or (at your option) any later version. # published by the Free Software Foundation; either version 2 of # modify it under the terms of the GNU General Public License as # This program is free software; you can redistribute it and/or # # project. # See file CREDITS for list of people who contributed to this # # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # (C) Copyright 2000 # # (C) Marko Mlinar, based on ppcboot
\ No newline at end of file
|
|
/services/arp.c
0,0 → 1,110
/* |
* (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 "common.h" |
#include "support.h" |
#include "net.h" |
#include "bootp.h" |
#include "tftp.h" |
#include "arp.h" |
|
|
#define TIMEOUT 5 /* Seconds before trying ARP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
|
static void ArpHandler(unsigned char *pkt, unsigned dest, unsigned src, unsigned len); |
static void ArpTimeout(void); |
|
int ArpTry = 0; |
|
/* |
* Handle a ARP received packet. |
*/ |
static void |
ArpHandler(unsigned char *pkt, unsigned dest, unsigned src, unsigned len) |
{ |
/* Check if the frame is really an ARP reply */ |
if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) { |
#ifdef DEBUG |
printf("Got good ARP - start TFTP\n"); |
#endif |
TftpStart (); |
} |
} |
|
|
/* |
* Timeout on ARP request. |
*/ |
static void |
ArpTimeout(void) |
{ |
if (ArpTry >= TIMEOUT_COUNT) { |
printf("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
} else { |
NetSetTimeout (TIMEOUT * IN_CLK, ArpTimeout); |
ArpRequest (); |
} |
} |
|
|
void |
ArpRequest (void) |
{ |
int i; |
volatile unsigned char *pkt; |
ARP_t * arp; |
|
printf("ARP broadcast %d\n", ++ArpTry); |
pkt = NetTxPacket; |
|
NetSetEther(pkt, NetBcastAddr, PROT_ARP); |
pkt += ETHER_HDR_SIZE; |
|
arp = (ARP_t *)pkt; |
|
arp->ar_hrd = ARP_ETHER; |
arp->ar_pro = PROT_IP; |
arp->ar_hln = 6; |
arp->ar_pln = 4; |
arp->ar_op = ARPOP_REQUEST; |
NetCopyEther(&arp->ar_data[0], NetOurEther); /* source ET addr */ |
*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; /* source IP addr */ |
for (i=10; i<16; ++i) { |
arp->ar_data[i] = 0; /* dest ET addr = 0 */ |
} |
|
if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { |
*(IPaddr_t *)(&arp->ar_data[16]) = NetOurGatewayIP; |
} else { |
*(IPaddr_t *)(&arp->ar_data[16]) = NetServerIP; |
} |
|
|
NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); |
|
NetSetTimeout(TIMEOUT * IN_CLK, ArpTimeout); |
NetSetHandler(ArpHandler); |
} |
|
/services/tftp.h
0,0 → 1,21
/* |
* LiMon - BOOTP/TFTP. |
* |
* Copyright 1994, 1995, 2000 Neil Russell. |
* (See License) |
*/ |
|
#ifndef __TFTP_H__ |
#define __TFTP_H__ |
|
/**********************************************************************/ |
/* |
* Global functions and variables. |
*/ |
|
/* tftp.c */ |
extern void TftpStart (void); /* Begin TFTP get */ |
|
/**********************************************************************/ |
|
#endif /* __TFTP_H__ */ |
/services/bootp.c
0,0 → 1,863
/* |
* Based on LiMon - BOOTP. |
* |
* Copyright 1994, 1995, 2000 Neil Russell. |
* (See License) |
* Copyright 2000 Roland Borde |
* Copyright 2000 Paolo Scaffardi |
*/ |
|
#if 0 |
#define DEBUG 1 /* general debug */ |
#define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */ |
#endif |
|
#ifdef DEBUG_BOOTP_EXT |
#define debug_ext(fmt,args...) printf (fmt ,##args) |
#else |
#define debug_ext(fmt,args...) |
#endif |
|
#include "common.h" |
#include "net.h" |
#include "bootp.h" |
#include "tftp.h" |
#include "arp.h" |
|
#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ |
|
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
|
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
|
#define PORT_BOOTPS 67 /* BOOTP server UDP port */ |
#define PORT_BOOTPC 68 /* BOOTP client UDP port */ |
|
#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */ |
#define CONFIG_DHCP_MIN_EXT_LEN 64 |
#endif |
|
ulong BootpID; |
int BootpTry; |
#ifdef CONFIG_BOOTP_RANDOM_DELAY |
ulong seed1, seed2; |
#endif |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
dhcp_state_t dhcp_state = INIT; |
unsigned int dhcp_leasetime = 0; |
static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len); |
|
/* For Debug */ |
char *dhcpmsg2str(int type) |
{ |
switch (type) { |
case 1: return "DHCPDISCOVER"; break; |
case 2: return "DHCPOFFER"; break; |
case 3: return "DHCPREQUEST"; break; |
case 4: return "DHCPDECLINE"; break; |
case 5: return "DHCPACK"; break; |
case 6: return "DHCPNACK"; break; |
case 7: return "DHCPRELEASE"; break; |
default: return "UNKNOWN/INVALID MSG TYPE"; break; |
} |
} |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */ |
extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL */ |
#endif |
|
#endif /* CFG_CMD_DHCP */ |
|
static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp = (Bootp_t *) pkt; |
int retval = 0; |
|
if (dest != PORT_BOOTPC || src != PORT_BOOTPS) |
retval = -1; |
if (len < sizeof (Bootp_t) - OPT_SIZE) |
retval = -2; |
if (bp->bp_op != OP_BOOTREQUEST && |
bp->bp_op != OP_BOOTREPLY && |
bp->bp_op != DHCP_OFFER && |
bp->bp_op != DHCP_ACK && |
bp->bp_op != DHCP_NAK ) { |
retval = -3; |
} |
if (bp->bp_htype != HWT_ETHER) |
retval = -4; |
if (bp->bp_hlen != HWL_ETHER) |
retval = -5; |
if (bp->bp_id != BootpID) |
retval = -6; |
|
debug ("Filtering pkt = %d\n", retval); |
|
return retval; |
} |
|
/* |
* Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet |
*/ |
void BootpCopyNetParams(Bootp_t *bp) |
{ |
NetOurIP = bp->bp_yiaddr; |
NetServerIP = bp->bp_siaddr; |
NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src); |
copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); |
|
debug ("Bootfile: %s\n", BootFile); |
|
/* Propagate to environment: |
* don't delete exising entry when BOOTP / DHCP reply does |
* not contain a new value |
*/ |
if (*BootFile) { |
setenv ("bootfile", BootFile); |
} |
} |
|
static int truncate_sz (const char *name, int maxlen, int curlen) |
{ |
if (curlen >= maxlen) { |
printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n", |
name, curlen, maxlen); |
curlen = maxlen - 1; |
} |
return (curlen); |
} |
|
#if !(CONFIG_COMMANDS & CFG_CMD_DHCP) |
|
static void BootpVendorFieldProcess(u8 *ext) |
{ |
int size = *(ext+1) ; |
|
debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, *(ext+1)); |
|
NetBootFileSize = 0; |
|
switch (*ext) { |
/* Fixed length fields */ |
case 1: /* Subnet mask */ |
if (NetOurSubnetMask == 0) |
memcpy(&NetOurSubnetMask, ext+2, 4); |
break; |
case 2: /* Time offset - Not yet supported */ |
break; |
/* Variable length fields */ |
case 3: /* Gateways list */ |
if (NetOurGatewayIP == 0) { |
memcpy(&NetOurGatewayIP, ext+2, 4); |
} |
break; |
case 4: /* Time server - Not yet supported */ |
break; |
case 5: /* IEN-116 name server - Not yet supported */ |
break; |
case 6: |
if (NetOurDNSIP == 0) { |
memcpy(&NetOurDNSIP, ext+2, 4); |
} |
break; |
case 7: /* Log server - Not yet supported */ |
break; |
case 8: /* Cookie/Quote server - Not yet supported */ |
break; |
case 9: /* LPR server - Not yet supported */ |
break; |
case 10: /* Impress server - Not yet supported */ |
break; |
case 11: /* RPL server - Not yet supported */ |
break; |
case 12: /* Host name */ |
if (NetOurHostName[0] == 0) { |
size = truncate_sz("Host Name", sizeof(NetOurHostName), size); |
memcpy(&NetOurHostName, ext+2, size); |
NetOurHostName[size] = 0 ; |
} |
break; |
case 13: /* Boot file size */ |
memcpy(&NetBootFileSize, ext+2, size); |
break; |
case 14: /* Merit dump file - Not yet supported */ |
break; |
case 15: /* Domain name - Not yet supported */ |
break; |
case 16: /* Swap server - Not yet supported */ |
break; |
case 17: /* Root path */ |
if (NetOurRootPath[0] == 0) { |
size = truncate_sz("Root Path", sizeof(NetOurRootPath), size); |
memcpy(&NetOurRootPath, ext+2, size); |
NetOurRootPath[size] = 0 ; |
} |
break; |
case 18: /* Extension path - Not yet supported */ |
/* |
* This can be used to send the informations of the |
* vendor area in another file that the client can |
* access via TFTP. |
*/ |
break; |
/* IP host layer fields */ |
case 40: /* NIS Domain name */ |
if (NetOurNISDomain[0] == 0) { |
size = truncate_sz ("NIS Domain Name", |
sizeof(NetOurNISDomain), |
size); |
memcpy(&NetOurNISDomain, ext+2, size); |
NetOurNISDomain[size] = 0 ; |
} |
break; |
/* Application layer fields */ |
case 43: /* Vendor specific info - Not yet supported */ |
/* |
* Binary informations to exchange specific |
* product information. |
*/ |
break; |
/* Reserved (custom) fields (128..254) */ |
} |
} |
|
static void BootpVendorProcess(u8 *ext, int size) |
{ |
u8 *end = ext + size ; |
|
debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size); |
|
while ((ext < end) && (*ext != 0xff)) { |
if (*ext == 0) { |
ext ++ ; |
} else { |
u8 *opt = ext ; |
ext += ext[1] + 2 ; |
if (ext <= end) |
BootpVendorFieldProcess (opt) ; |
} |
} |
|
#ifdef DEBUG_BOOTP_EXT |
printf("[BOOTP] Received fields: \n"); |
if (NetOurSubnetMask) { |
puts ("NetOurSubnetMask : "); |
print_IPaddr (NetOurSubnetMask); |
putc('\n'); |
} |
|
if (NetOurGatewayIP) { |
puts ("NetOurGatewayIP : "); |
print_IPaddr (NetOurGatewayIP); |
putc('\n'); |
} |
|
if (NetBootFileSize) { |
printf("NetBootFileSize : %d\n", NetBootFileSize); |
} |
|
if (NetOurHostName[0]) { |
printf("NetOurHostName : %s\n", NetOurHostName); |
} |
|
if (NetOurRootPath[0]) { |
printf("NetOurRootPath : %s\n", NetOurRootPath); |
} |
|
if (NetOurNISDomain[0]) { |
printf("NetOurNISDomain : %s\n", NetOurNISDomain); |
} |
#endif /* DEBUG_BOOTP_EXT */ |
} |
|
/* |
* Handle a BOOTP received packet. |
*/ |
static void |
BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp; |
char *s; |
|
debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n", |
src, dest, len, sizeof (Bootp_t)); |
|
bp = (Bootp_t *)pkt; |
|
if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ |
return; |
|
/* |
* Got a good BOOTP reply. Copy the data into our variables. |
*/ |
#ifdef CONFIG_STATUS_LED |
status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF); |
#endif |
|
BootpCopyNetParams(bp); /* Store net parameters from reply */ |
|
/* Retrieve extended informations (we must parse the vendor area) */ |
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
BootpVendorProcess(&bp->bp_vend[4], len); |
|
NetSetTimeout(0, (thand_f *)0); |
|
debug ("Got good BOOTP\n"); |
|
if (((s = getenv("autoload")) != NULL) && (*s == 'n')) { |
/* |
* Just use BOOTP to configure system; |
* Do not use TFTP to load the bootfile. |
*/ |
NetState = NETLOOP_SUCCESS; |
return; |
} |
|
/* Send ARP request to get TFTP server ethernet address. |
* This automagically starts TFTP, too. |
*/ |
ArpRequest(); |
} |
#endif /* !CFG_CMD_DHCP */ |
|
/* |
* Timeout on BOOTP/DHCP request. |
*/ |
static void |
BootpTimeout(void) |
{ |
if (BootpTry >= TIMEOUT_COUNT) { |
puts ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
} else { |
NetSetTimeout (TIMEOUT * CFG_HZ, BootpTimeout); |
BootpRequest (); |
} |
} |
|
/* |
* Initialize BOOTP extension fields in the request. |
*/ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP) |
{ |
u8 *start = e ; |
u8 *cnt; |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
u8 *x; |
#endif |
|
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
|
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = message_type; |
|
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576-312+OPT_SIZE) >> 8; |
*e++ = (576-312+OPT_SIZE) & 0xff; |
|
if ( ServerID ) { |
*e++ = 54; /* ServerID */ |
*e++ = 4; |
*e++ = ServerID >> 24; |
*e++ = ServerID >> 16; |
*e++ = ServerID >> 8; |
*e++ = ServerID & 0xff; |
} |
|
if ( RequestedIP ) { |
*e++ = 50; /* Requested IP */ |
*e++ = 4; |
*e++ = RequestedIP >> 24; |
*e++ = RequestedIP >> 16; |
*e++ = RequestedIP >> 8; |
*e++ = RequestedIP & 0xff; |
} |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
if ((x = dhcp_vendorex_prep (e))) |
return x - start ; |
#endif |
|
*e++ = 55; /* Parameter Request List */ |
cnt = e++; /* Pointer to count of requested items */ |
*cnt = 0; |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) |
*e++ = 1; /* Subnet Mask */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) |
*e++ = 3; /* Router Option */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) |
*e++ = 6; /* DNS Server(s) */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) |
*e++ = 12; /* Hostname */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) |
*e++ = 13; /* Boot File Size */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) |
*e++ = 17; /* Boot path */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) |
*e++ = 40; /* NIS Domain name request */ |
*cnt += 1; |
#endif |
*e++ = 255; /* End of the list */ |
|
/* Pad to minimal length */ |
#ifdef CONFIG_DHCP_MIN_EXT_LEN |
while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) |
*e++ = 0; |
#endif |
|
return e - start ; |
} |
|
#else /* CFG_CMD_DHCP */ |
/* |
* Warning: no field size check - change CONFIG_BOOTP_MASK at your own risk! |
*/ |
static int BootpExtended (u8 *e) |
{ |
u8 *start = e ; |
|
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = DHCP_DISCOVER; |
|
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576-312+OPT_SIZE) >> 16; |
*e++ = (576-312+OPT_SIZE) & 0xff; |
#endif /* CFG_CMD_DHCP */ |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) |
*e++ = 1; /* Subnet mask request */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) |
*e++ = 3; /* Default gateway request */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) |
*e++ = 6; /* Domain Name Server */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) |
*e++ = 12; /* Host name request */ |
*e++ = 32; |
e += 32; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) |
*e++ = 13; /* Boot file size */ |
*e++ = 2; |
e += 2; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) |
*e++ = 17; /* Boot path */ |
*e++ = 32; |
e += 32; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) |
*e++ = 40; /* NIS Domain name request */ |
*e++ = 32; |
e += 32; |
#endif |
|
*e++ = 255; /* End of the list */ |
|
return e - start ; |
} |
#endif /* CFG_CMD_DHCP */ |
|
void |
BootpRequest (void) |
{ |
volatile uchar *pkt, *iphdr; |
Bootp_t *bp; |
int ext_len, pktlen, iplen; |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
dhcp_state = INIT; |
#endif |
|
#ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ |
unsigned char bi_enetaddr[6]; |
int reg; |
char *e,*s; |
uchar tmp[64]; |
ulong tst1, tst2, sum, m_mask, m_value = 0; |
|
if (BootpTry ==0) { |
/* get our mac */ |
reg = getenv_r ("ethaddr", tmp, sizeof(tmp)); |
s = (reg > 0) ? tmp : NULL; |
|
for (reg=0; reg<6; ++reg) { |
bi_enetaddr[reg] = s ? simple_strtoul(s, &e, 16) : 0; |
if (s) { |
s = (*e) ? e+1 : e; |
} |
} |
#ifdef DEBUG |
printf("BootpRequest => Our Mac: "); |
for (reg=0; reg<6; reg++) { |
printf ("%x%c", |
bi_enetaddr[reg], |
reg==5 ? '\n' : ':'); |
} |
#endif /* DEBUG */ |
|
/* Mac-Manipulation 2 get seed1 */ |
tst1=0; |
tst2=0; |
for (reg=2; reg<6; reg++) { |
tst1 = tst1 << 8; |
tst1 = tst1 | bi_enetaddr[reg]; |
} |
for (reg=0; reg<2; reg++) { |
tst2 = tst2 | bi_enetaddr[reg]; |
tst2 = tst2 << 8; |
} |
|
seed1 = tst1^tst2; |
|
/* Mirror seed1*/ |
m_mask=0x1; |
for (reg=1;reg<=32;reg++) { |
m_value |= (m_mask & seed1); |
seed1 = seed1 >> 1; |
m_value = m_value << 1; |
} |
seed1 = m_value; |
seed2 = 0xB78D0945; |
} |
|
/* Random Number Generator */ |
|
for (reg=0;reg<=0;reg++) { |
sum = seed1 + seed2; |
if (sum < seed1 || sum < seed2) |
sum++; |
seed2 = seed1; |
seed1 = sum; |
|
if (BootpTry<=2) { /* Start with max 1024 * 1ms */ |
sum = sum >> (22-BootpTry); |
} else { /*After 3rd BOOTP request max 8192 * 1ms */ |
sum = sum >> 19; |
} |
} |
|
printf ("Random delay: %ld ms...\n", sum); |
for (reg=0; reg <sum; reg++) { |
udelay(1000); /*Wait 1ms*/ |
} |
#endif /* CONFIG_BOOTP_RANDOM_DELAY */ |
|
printf("BOOTP broadcast %d\n", ++BootpTry); |
pkt = NetTxPacket; |
memset ((void*)pkt, 0, PKTSIZE); |
|
NetSetEther(pkt, NetBcastAddr, PROT_IP); |
pkt += ETHER_HDR_SIZE; |
|
/* |
* Next line results in incorrect packet size being transmitted, resulting |
* in errors in some DHCP servers, reporting missing bytes. Size must be |
* set in packet header after extension length has been determined. |
* C. Hallinan, DS4.COM, Inc. |
*/ |
/* NetSetIP(pkt, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */ |
iphdr = pkt; /* We need this later for NetSetIP() */ |
pkt += IP_HDR_SIZE; |
|
bp = (Bootp_t *)pkt; |
bp->bp_op = OP_BOOTREQUEST; |
bp->bp_htype = HWT_ETHER; |
bp->bp_hlen = HWL_ETHER; |
bp->bp_hops = 0; |
bp->bp_secs = SWAP16( get_timer(0) / CFG_HZ); |
bp->bp_ciaddr = 0; |
bp->bp_yiaddr = 0; |
bp->bp_siaddr = 0; |
bp->bp_giaddr = 0; |
NetCopyEther(bp->bp_chaddr, NetOurEther); |
copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file)); |
|
/* Request additional information from the BOOTP/DHCP server */ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
ext_len = DhcpExtended(bp->bp_vend, DHCP_DISCOVER, 0, 0); |
#else |
ext_len = BootpExtended(bp->bp_vend); |
#endif /* CFG_CMD_DHCP */ |
|
/* |
* Bootp ID is the lower 4 bytes of our ethernet address |
* plus the current time in HZ. |
*/ |
BootpID = ((ulong)NetOurEther[2] << 24) |
| ((ulong)NetOurEther[3] << 16) |
| ((ulong)NetOurEther[4] << 8) |
| (ulong)NetOurEther[5]; |
BootpID += get_timer(0); |
bp->bp_id = BootpID; |
|
/* |
* Calculate proper packet lengths taking into account the |
* variable size of the options field |
*/ |
pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + ext_len; |
iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len; |
NetSetIP(iphdr, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, iplen); |
NetSetTimeout(SELECT_TIMEOUT * CFG_HZ, BootpTimeout); |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
dhcp_state = SELECTING; |
NetSetHandler(DhcpHandler); |
#else |
NetSetHandler(BootpHandler); |
#endif /* CFG_CMD_DHCP */ |
NetSendPacket(NetTxPacket, pktlen); |
} |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
void DhcpOptionsProcess(char *popt) |
{ |
char *end = popt + BOOTP_HDR_SIZE; |
int oplen, size; |
|
while ( popt < end && *popt != 0xff ) { |
oplen = *(popt + 1); |
switch(*popt) { |
case 1: |
NetOurSubnetMask = *(IPaddr_t *)(popt + 2); |
break; |
case 3: |
NetOurGatewayIP = *(IPaddr_t *)(popt + 2); |
break; |
case 6: |
NetOurDNSIP = *(IPaddr_t *)(popt +2); |
break; |
case 12: |
size = truncate_sz ("Host Name", |
sizeof(NetOurHostName), |
oplen); |
memcpy(&NetOurHostName, popt+2, size); |
NetOurHostName[size] = 0 ; |
break; |
case 15: /* Ignore Domain Name Option */ |
break; |
case 17: |
size = truncate_sz ("Root Path", |
sizeof(NetOurRootPath), |
oplen); |
memcpy(&NetOurRootPath, popt+2, size); |
NetOurRootPath[size] = 0 ; |
break; |
case 51: |
dhcp_leasetime = *(unsigned int *)(popt + 2); |
break; |
case 53: /* Ignore Message Type Option */ |
break; |
case 54: |
NetServerIP = *(IPaddr_t *)(popt+2); |
break; |
case 58: /* Ignore Renewal Time Option */ |
break; |
case 59: /* Ignore Rebinding Time Option */ |
break; |
default: |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
if (dhcp_vendorex_proc(popt)) |
break; |
#endif |
printf("*** Unhandled DHCP Option in OFFER/ACK: %d\n", |
*popt); |
break; |
} |
popt += oplen + 2; /* Process next option */ |
} |
} |
|
static int DhcpMessageType(unsigned char *popt) |
{ |
if ((*(uint *)popt) != BOOTP_VENDOR_MAGIC) |
return -1; |
|
popt += 4; |
while ( *popt != 0xff ) { |
if ( *popt == 53 ) /* DHCP Message Type */ |
return *(popt + 2); |
popt += *(popt + 1) + 2; /* Scan through all options */ |
} |
return -1; |
} |
|
void DhcpSendRequestPkt(Bootp_t *bp_offer) |
{ |
volatile uchar *pkt, *iphdr; |
Bootp_t *bp; |
int pktlen, iplen, extlen; |
|
debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); |
pkt = NetTxPacket; |
memset ((void*)pkt, 0, PKTSIZE); |
|
NetSetEther(pkt, NetBcastAddr, PROT_IP); |
pkt += ETHER_HDR_SIZE; |
|
iphdr = pkt; /* We'll need this later to set proper pkt size */ |
pkt += IP_HDR_SIZE; |
|
bp = (Bootp_t *)pkt; |
bp->bp_op = OP_BOOTREQUEST; |
bp->bp_htype = HWT_ETHER; |
bp->bp_hlen = HWL_ETHER; |
bp->bp_hops = 0; |
bp->bp_secs = SWAP16( get_timer(0) / CFG_HZ); |
bp->bp_ciaddr = bp_offer->bp_ciaddr; |
bp->bp_yiaddr = bp_offer->bp_yiaddr; |
bp->bp_siaddr = bp_offer->bp_siaddr; |
bp->bp_giaddr = bp_offer->bp_giaddr; |
NetCopyEther(bp->bp_chaddr, NetOurEther); |
|
/* |
* ID is the id of the OFFER packet |
*/ |
|
bp->bp_id = bp_offer->bp_id; |
|
/* |
* Copy options from OFFER packet if present |
*/ |
extlen = DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetServerIP, bp->bp_yiaddr); |
|
pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen; |
iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; |
NetSetIP(iphdr, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, iplen); |
|
debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); |
NetSendPacket(NetTxPacket, pktlen); |
} |
|
/* |
* Handle DHCP received packets. |
*/ |
static void |
DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp = (Bootp_t *)pkt; |
|
debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
|
if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ |
return; |
|
debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
|
switch (dhcp_state) { |
case SELECTING: |
/* |
* Wait an appropriate time for any potential DHCPOFFER packets |
* to arrive. Then select one, and generate DHCPREQUEST response. |
* If filename is in format we recognize, assume it is a valid |
* OFFER from a server we want. |
*/ |
debug ("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file); |
#ifdef CFG_BOOTFILE_PREFIX |
if (strncmp(bp->bp_file, |
CFG_BOOTFILE_PREFIX, |
strlen(CFG_BOOTFILE_PREFIX)) == 0 ) { |
#endif /* CFG_BOOTFILE_PREFIX */ |
|
debug ("TRANSITIONING TO REQUESTING STATE\n"); |
dhcp_state = REQUESTING; |
#if 0 |
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
DhcpOptionsProcess(&bp->bp_vend[4]); |
|
#endif |
BootpCopyNetParams(bp); /* Store net params from reply */ |
|
NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout); |
DhcpSendRequestPkt(bp); |
#ifdef CFG_BOOTFILE_PREFIX |
} |
#endif /* CFG_BOOTFILE_PREFIX */ |
|
return; |
break; |
case REQUESTING: |
debug ("DHCP State: REQUESTING\n"); |
|
if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) { |
char *s; |
|
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
DhcpOptionsProcess(&bp->bp_vend[4]); |
BootpCopyNetParams(bp); /* Store net params from reply */ |
dhcp_state = BOUND; |
printf("DHCP client bound to address "); |
print_IPaddr(NetOurIP); |
printf("\n"); |
|
/* Obey the 'autoload' setting */ |
if (((s = getenv("autoload")) != NULL) && (*s == 'n')) { |
NetState = NETLOOP_SUCCESS; |
return; |
} |
/* Send ARP request to get TFTP server ethernet address. |
* This automagically starts TFTP, too. |
*/ |
ArpRequest(); |
return; |
} |
break; |
default: |
printf("DHCP: INVALID STATE\n"); |
break; |
} |
|
} |
|
void DhcpRequest(void) |
{ |
BootpRequest(); |
} |
#endif /* CFG_CMD_DHCP */ |
|
#endif /* CFG_CMD_NET */ |
/services/rarp.c
0,0 → 1,101
/* |
* (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 "common.h" |
#include "net.h" |
#include "bootp.h" |
#include "rarp.h" |
#include "tftp.h" |
|
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
|
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
|
|
int RarpTry; |
|
/* |
* Handle a RARP received packet. |
*/ |
static void |
RarpHandler(uchar * dummi0, unsigned dummi1, unsigned dummi2, unsigned dummi3) |
{ |
#ifdef DEBUG |
printf("Got good RARP\n"); |
#endif |
TftpStart (); |
} |
|
|
/* |
* Timeout on BOOTP request. |
*/ |
static void |
RarpTimeout(void) |
{ |
if (RarpTry >= TIMEOUT_COUNT) { |
puts ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
} else { |
NetSetTimeout (TIMEOUT * CFG_HZ, RarpTimeout); |
RarpRequest (); |
} |
} |
|
|
void |
RarpRequest (void) |
{ |
int i; |
volatile uchar *pkt; |
ARP_t * rarp; |
|
printf("RARP broadcast %d\n", ++RarpTry); |
pkt = NetTxPacket; |
|
NetSetEther(pkt, NetBcastAddr, PROT_RARP); |
pkt += ETHER_HDR_SIZE; |
|
rarp = (ARP_t *)pkt; |
|
rarp->ar_hrd = ARP_ETHER; |
rarp->ar_pro = PROT_IP; |
rarp->ar_hln = 6; |
rarp->ar_pln = 4; |
rarp->ar_op = RARPOP_REQUEST; |
NetCopyEther(&rarp->ar_data[0], NetOurEther); /* source ET addr */ |
*(IPaddr_t *)(&rarp->ar_data[6]) = NetOurIP; /* source IP addr */ |
NetCopyEther(&rarp->ar_data[10], NetOurEther); /* dest ET addr = source ET addr ??*/ |
/* dest. IP addr set to broadcast */ |
for (i = 0; i <= 3; i++) { |
rarp->ar_data[16 + i] = 0xff; |
} |
|
NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); |
|
NetSetTimeout(TIMEOUT * CFG_HZ, RarpTimeout); |
NetSetHandler(RarpHandler); |
} |
|
#endif /* CFG_CMD_NET */ |
/services/net.c
0,0 → 1,644
/* |
* Copied from Linux Monitor (LiMon) - Networking. |
* |
* Copyright 1994 - 2000 Neil Russell. |
* (See License) |
* Copyright 2000 Roland Borde |
* Copyright 2000 Paolo Scaffardi |
* Copyright 2000, 2001 Wolfgang Denk |
*/ |
|
/* |
* General Desription: |
* |
* The user interface supports commands for BOOTP, RARP, and TFTP. |
* Also, we support ARP internally. Depending on available data, |
* these interact as follows: |
* |
* BOOTP: |
* |
* Prerequisites: - own ethernet address |
* We want: - own IP address |
* - TFTP server IP address |
* - name of bootfile |
* Next step: ARP |
* |
* RARP: |
* |
* Prerequisites: - own ethernet address |
* We want: - own IP address |
* - TFTP server IP address |
* Next step: ARP |
* |
* ARP: |
* |
* Prerequisites: - own ethernet address |
* - own IP address |
* - TFTP server IP address |
* We want: - TFTP server ethernet address |
* Next step: TFTP |
* |
* DHCP: |
* |
* Prerequisites: - own ethernet address |
* We want: - IP, Netmask, ServerIP, Gateway IP |
* - bootfilename, lease time |
* Next step: - TFTP |
* |
* TFTP: |
* |
* Prerequisites: - own ethernet address |
* - own IP address |
* - TFTP server IP address |
* - TFTP server ethernet address |
* - name of bootfile (if unknown, we use a default name |
* derived from our own IP address) |
* We want: - load the boot file |
* Next step: none |
*/ |
|
|
#include "common.h" |
#include "support.h" |
#include "net.h" |
#include "bootp.h" |
#include "tftp.h" |
#include "rarp.h" |
#include "arp.h" |
#include "eth.h" |
|
#if 0 |
#define ET_DEBUG |
#endif |
|
/** BOOTP EXTENTIONS **/ |
|
IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ |
IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ |
IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ |
char NetOurNISDomain[32]={0,}; /* Our NIS domain */ |
char NetOurHostName[32]={0,}; /* Our hostname */ |
char NetOurRootPath[64]={0,}; /* Our bootpath */ |
unsigned short NetBootFileSize=0; /* Our bootfile size in blocks */ |
|
/** END OF BOOTP EXTENTIONS **/ |
|
unsigned long NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ |
unsigned char NetOurEther[6]; /* Our ethernet address */ |
unsigned char NetServerEther[6] = /* Boot server enet address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ |
IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ |
volatile unsigned char *NetRxPkt; /* Current receive packet */ |
int NetRxPktLen; /* Current rx packet length */ |
unsigned NetIPID; /* IP packet ID */ |
unsigned char NetBcastAddr[6] = /* Ethernet bcast address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
int NetState; /* Network loop state */ |
|
char BootFile[128]; /* Boot File name */ |
|
volatile unsigned char PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; |
|
volatile unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets */ |
|
static rxhand_f *packetHandler; /* Current RX packet handler */ |
static thand_f *timeHandler; /* Current timeout handler */ |
static unsigned long timeValue; /* Current timeout value */ |
volatile unsigned char *NetTxPacket = 0; /* THE transmit packet */ |
|
static int net_check_prereq (proto_t protocol); |
|
/**********************************************************************/ |
/* |
* Main network processing loop. |
*/ |
int |
NetLoop(proto_t protocol) |
{ |
#if 1 |
if (!NetTxPacket) { |
int i; |
|
/* |
* Setup packet buffers, aligned correctly. |
*/ |
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); |
NetTxPacket -= (unsigned long)NetTxPacket % PKTALIGN; |
for (i = 0; i < PKTBUFSRX; i++) { |
NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; |
} |
} |
|
eth_halt(); |
eth_init(NetReceive); |
|
restart: |
NetCopyEther(NetOurEther, global.eth_add); |
|
NetState = NETLOOP_CONTINUE; |
|
/* |
* Start the ball rolling with the given start function. From |
* here on, this code is a state machine driven by received |
* packets and timer events. |
*/ |
|
if (protocol == TFTP) { /* TFTP */ |
NetOurIP = global.ip; |
NetServerIP = global.srv_ip; |
NetOurGatewayIP = global.gw_ip; |
NetOurSubnetMask= global.mask; |
|
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
|
/* always use ARP to get server ethernet address */ |
ArpTry = 0; |
ArpRequest (); |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
} else if (protocol == DHCP) { |
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
|
/* Start with a clean slate... */ |
NetOurIP = 0; |
NetServerIP = 0; |
DhcpRequest(); /* Basically same as BOOTP */ |
|
#endif /* CFG_CMD_DHCP */ |
|
} else { /* BOOTP or RARP */ |
|
/* |
* initialize our IP addr to 0 in order to accept ANY |
* IP addr assigned to us by the BOOTP / RARP server |
*/ |
NetOurIP = 0; |
NetServerIP = 0; |
|
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
#ifdef BOOTP |
if (protocol == BOOTP) { |
BootpTry = 0; |
BootpRequest (); |
} |
#endif |
#ifdef RARP |
if { |
RarpTry = 0; |
RarpRequest (); |
} |
#endif |
} |
|
NetBootFileXferSize = 0; |
|
/* |
* Main packet reception loop. Loop receiving packets until |
* someone sets `NetQuit'. |
*/ |
for (;;) { |
// WATCHDOG_RESET(); |
/* |
* Check the ethernet for a new packet. The ethernet |
* receive routine will process it. |
*/ |
eth_rx(); |
|
/* |
* Abort if ctrl-c was pressed. |
*/ |
if (ctrlc()) { |
eth_halt(); |
printf("\nAbort\n"); |
return 0; |
} |
|
|
/* |
* Check for a timeout, and run the timeout handler |
* if we have one. |
*/ |
if (timeHandler && (get_timer(0) > timeValue)) { |
thand_f *x; |
|
x = timeHandler; |
timeHandler = (thand_f *)0; |
(*x)(); |
} |
|
|
switch (NetState) { |
|
case NETLOOP_RESTART: |
goto restart; |
|
case NETLOOP_SUCCESS: |
if (NetBootFileXferSize > 0) { |
printf("Bytes transferred = %ld (%lx hex)\n", |
NetBootFileXferSize, |
NetBootFileXferSize); |
} |
eth_halt(); |
return NetBootFileXferSize; |
|
case NETLOOP_FAIL: |
return 0; |
} |
} |
#endif |
} |
|
/**********************************************************************/ |
|
|
#if 1 |
void |
NetStartAgain(void) |
{ |
NetState = NETLOOP_RESTART; |
} |
|
/**********************************************************************/ |
/* |
* Miscelaneous bits. |
*/ |
|
void |
NetSetHandler(rxhand_f * f) |
{ |
packetHandler = f; |
} |
|
|
void |
NetSetTimeout(int iv, thand_f * f) |
{ |
if (iv == 0) { |
timeHandler = (thand_f *)0; |
} else { |
timeHandler = f; |
timeValue = get_timer(0) + iv; |
} |
} |
|
|
void |
NetSendPacket(volatile unsigned char * pkt, int len) |
{ |
unsigned char *p; |
|
p = eth_get_tx_buf(); |
memcpy(p, (void *)pkt, len); |
eth_send(p, len); |
} |
|
|
|
void |
NetReceive(volatile unsigned char * pkt, int len) |
{ |
Ethernet_t *et; |
IP_t *ip; |
ARP_t *arp; |
int x; |
|
|
NetRxPkt = pkt; |
NetRxPktLen = len; |
et = (Ethernet_t *)pkt; |
|
x = SWAP16(et->et_protlen); |
|
if (x < 1514) { |
/* |
* Got a 802 packet. Check the other protocol field. |
*/ |
x = SWAP16(et->et_prot); |
ip = (IP_t *)(pkt + E802_HDR_SIZE); |
len -= E802_HDR_SIZE; |
} else { |
ip = (IP_t *)(pkt + ETHER_HDR_SIZE); |
len -= ETHER_HDR_SIZE; |
} |
|
#ifdef ET_DEBUG |
printf("Receive from protocol 0x%x\n", x); |
#endif |
|
switch (x) { |
|
case PROT_ARP: |
/* |
* We have to deal with two types of ARP packets: |
* - REQUEST packets will be answered by sending our |
* IP address - if we know it. |
* - REPLY packates are expected only after we asked |
* for the TFTP server's or the gateway's ethernet |
* address; so if we receive such a packet, we set |
* the server ethernet address |
*/ |
#ifdef ET_DEBUG |
printf("Got ARP\n"); |
#endif |
arp = (ARP_t *)ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
if (SWAP16(arp->ar_hrd) != ARP_ETHER) { |
return; |
} |
if (SWAP16(arp->ar_pro) != PROT_IP) { |
return; |
} |
if (arp->ar_hln != 6) { |
return; |
} |
if (arp->ar_pln != 4) { |
return; |
} |
|
if (NetOurIP == 0 || |
*((IPaddr_t *)&arp->ar_data[16]) != NetOurIP) { |
return; |
} |
|
switch (SWAP16(arp->ar_op)) { |
case ARPOP_REQUEST: /* reply with our IP address */ |
#ifdef ET_DEBUG |
printf("Got ARP REQUEST, return our IP\n"); |
#endif |
NetSetEther((unsigned char *)et, et->et_src, PROT_ARP); |
arp->ar_op = SWAP16(ARPOP_REPLY); |
NetCopyEther(&arp->ar_data[10], &arp->ar_data[0]); |
NetCopyEther(&arp->ar_data[0], NetOurEther); |
*(IPaddr_t *)(&arp->ar_data[16]) = |
*(IPaddr_t *)(&arp->ar_data[6]); |
*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; |
NetSendPacket((unsigned char *)et,((unsigned char *)arp-pkt)+ARP_HDR_SIZE); |
return; |
case ARPOP_REPLY: /* set TFTP server eth addr */ |
#ifdef ET_DEBUG |
printf("Got ARP REPLY, set server/gtwy eth addr\n"); |
#endif |
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
(*packetHandler)(0,0,0,0); /* start TFTP */ |
return; |
default: |
#ifdef ET_DEBUG |
printf("Unexpected ARP opcode 0x%x\n", SWAP16(arp->ar_op)); |
#endif |
return; |
} |
|
case PROT_RARP: |
#ifdef ET_DEBUG |
printf("Got RARP\n"); |
#endif |
arp = (ARP_t *)ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
|
if ((SWAP16(arp->ar_op) != RARPOP_REPLY) || |
(SWAP16(arp->ar_hrd) != ARP_ETHER) || |
(SWAP16(arp->ar_pro) != PROT_IP) || |
(arp->ar_hln != 6) || (arp->ar_pln != 4)) { |
|
printf("invalid RARP header\n"); |
} else { |
NetOurIP = *((IPaddr_t *)&arp->ar_data[16]); |
NetServerIP = *((IPaddr_t *)&arp->ar_data[6]); |
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
|
(*packetHandler)(0,0,0,0); |
} |
break; |
|
case PROT_IP: |
#ifdef ET_DEBUG |
printf("Got IP\n"); |
#endif |
if (len < IP_HDR_SIZE) { |
debug ("len bad %d < %d\n", len, IP_HDR_SIZE); |
return; |
} |
if (len < SWAP16(ip->ip_len)) { |
printf("len bad %d < %d\n", len, SWAP16(ip->ip_len)); |
return; |
} |
len = SWAP16(ip->ip_len); |
#ifdef ET_DEBUG |
printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); |
#endif |
if ((ip->ip_hl_v & 0xf0) != 0x40) { |
return; |
} |
if (ip->ip_off & SWAP16c(0x1fff)) { /* Can't deal w/ fragments */ |
return; |
} |
if (!NetCksumOk((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2)) { |
printf("checksum bad\n"); |
return; |
} |
if (NetOurIP && |
ip->ip_dst != NetOurIP && |
ip->ip_dst != 0xFFFFFFFF) { |
return; |
} |
/* |
* watch for ICMP host redirects |
* |
* There is no real handler code (yet). We just watch |
* for ICMP host redirect messages. In case anybody |
* sees these messages: please contact me |
* (wd@denx.de), or - even better - send me the |
* necessary fixes :-) |
* |
* Note: in all cases where I have seen this so far |
* it was a problem with the router configuration, |
* for instance when a router was configured in the |
* BOOTP reply, but the TFTP server was on the same |
* subnet. So this is probably a warning that your |
* configuration might be wrong. But I'm not really |
* sure if there aren't any other situations. |
*/ |
if (ip->ip_p == IPPROTO_ICMP) { |
ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); |
|
if (icmph->type != ICMP_REDIRECT) |
return; |
if (icmph->code != ICMP_REDIR_HOST) |
return; |
printf (" ICMP Host Redirect to "); |
print_IPaddr(icmph->un.gateway); |
putc(' '); |
} else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ |
return; |
} |
|
/* |
* IP header OK. Pass the packet to the current handler. |
*/ |
(*packetHandler)((unsigned char *)ip +IP_HDR_SIZE, |
SWAP16(ip->udp_dst), |
SWAP16(ip->udp_src), |
SWAP16(ip->udp_len) - 8); |
|
break; |
} |
} |
|
|
/**********************************************************************/ |
|
static int net_check_prereq (proto_t protocol) |
{ |
switch (protocol) { |
case ARP: /* nothing to do */ |
break; |
|
case TFTP: |
if (NetServerIP == 0) { |
printf ("*** ERROR: `serverip' not set\n"); |
return (1); |
} |
|
if (NetOurIP == 0) { |
printf ("*** ERROR: `ipaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
|
case DHCP: |
case RARP: |
case BOOTP: |
if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { |
printf ("*** ERROR: `ethaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
} |
return (0); /* OK */ |
} |
/**********************************************************************/ |
|
int |
NetCksumOk(unsigned char * ptr, int len) |
{ |
return !((NetCksum(ptr, len) + 1) & 0xfffe); |
} |
|
|
unsigned |
NetCksum(unsigned char * ptr, int len) |
{ |
unsigned long xsum; |
|
xsum = 0; |
while (len-- > 0) |
xsum += *((unsigned short *)ptr)++; |
xsum = (xsum & 0xffff) + (xsum >> 16); |
xsum = (xsum & 0xffff) + (xsum >> 16); |
return (xsum & 0xffff); |
} |
|
|
void |
NetCopyEther(volatile unsigned char * to, unsigned char * from) |
{ |
int i; |
|
for (i = 0; i < 6; i++) |
*to++ = *from++; |
} |
|
|
void |
NetSetEther(volatile unsigned char * xet, unsigned char * addr, unsigned long prot) |
{ |
volatile Ethernet_t *et = (Ethernet_t *)xet; |
|
NetCopyEther(et->et_dest, addr); |
NetCopyEther(et->et_src, NetOurEther); |
et->et_protlen = SWAP16(prot); |
} |
|
|
void |
NetSetIP(volatile unsigned char * xip, IPaddr_t dest, int dport, int sport, int len) |
{ |
volatile IP_t *ip = (IP_t *)xip; |
|
/* |
* If the data is an odd number of bytes, zero the |
* byte after the last byte so that the checksum |
* will work. |
*/ |
if (len & 1) |
xip[IP_HDR_SIZE + len] = 0; |
|
/* |
* Construct an IP and UDP header. |
(need to set no fragment bit - XXX) |
*/ |
ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ |
ip->ip_tos = 0; |
ip->ip_len = SWAP16(IP_HDR_SIZE + len); |
ip->ip_id = SWAP16(NetIPID++); |
ip->ip_off = SWAP16c(0x4000); /* No fragmentation */ |
ip->ip_ttl = 255; |
ip->ip_p = 17; /* UDP */ |
ip->ip_sum = 0; |
ip->ip_src = NetOurIP; |
ip->ip_dst = dest; |
ip->udp_src = SWAP16(sport); |
ip->udp_dst = SWAP16(dport); |
ip->udp_len = SWAP16(8 + len); |
ip->udp_xsum = 0; |
ip->ip_sum = ~NetCksum((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2); |
} |
|
void copy_filename (unsigned char *dst, unsigned char *src, int size) |
{ |
if (*src && (*src == '"')) { |
++src; |
--size; |
} |
|
while ((--size > 0) && *src && (*src != '"')) { |
*dst++ = *src++; |
} |
*dst = '\0'; |
} |
|
void ip_to_string (IPaddr_t x, char *s) |
{ |
char num[] = "0123456789ABCDEF"; |
int i; |
|
x = SWAP32(x); |
|
for(i = 28; i >= 0; i -= 4) |
*s++ = num[((x >> i) & 0x0f)]; |
*s = 0; |
} |
|
void print_IPaddr (IPaddr_t x) |
{ |
char tmp[12]; |
|
ip_to_string(x, tmp); |
|
printf(tmp); |
} |
|
#endif |
/services/arp.h
0,0 → 1,40
/* |
* (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 |
*/ |
|
|
#ifndef __ARP_H__ |
#define __ARP_H__ |
|
/**********************************************************************/ |
/* |
* Global functions and variables. |
*/ |
|
extern int ArpTry; |
|
extern void ArpRequest (void); /* Send a ARP request */ |
|
/**********************************************************************/ |
|
#endif /* __ARP_H__ */ |
|
/services/bootp.h
0,0 → 1,95
/* |
* Copied from LiMon - BOOTP. |
* |
* Copyright 1994, 1995, 2000 Neil Russell. |
* (See License) |
* Copyright 2000 Paolo Scaffardi |
*/ |
|
#ifndef __BOOTP_H__ |
#define __BOOTP_H__ |
|
#ifndef __NET_H__ |
#include "net.h" |
#endif /* __NET_H__ */ |
|
/**********************************************************************/ |
|
/* |
* BOOTP header. |
*/ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
#define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */ |
#else |
#define OPT_SIZE 64 |
#endif |
|
typedef struct |
{ |
unsigned char bp_op; /* Operation */ |
# define OP_BOOTREQUEST 1 |
# define OP_BOOTREPLY 2 |
unsigned char bp_htype; /* Hardware type */ |
# define HWT_ETHER 1 |
unsigned char bp_hlen; /* Hardware address length */ |
# define HWL_ETHER 6 |
unsigned char bp_hops; /* Hop count (gateway thing) */ |
unsigned long bp_id; /* Transaction ID */ |
unsigned short bp_secs; /* Seconds since boot */ |
unsigned short bp_spare1; /* Alignment */ |
IPaddr_t bp_ciaddr; /* Client IP address */ |
IPaddr_t bp_yiaddr; /* Your (client) IP address */ |
IPaddr_t bp_siaddr; /* Server IP address */ |
IPaddr_t bp_giaddr; /* Gateway IP address */ |
unsigned char bp_chaddr[16]; /* Client hardware address */ |
char bp_sname[64]; /* Server host name */ |
char bp_file[128]; /* Boot file name */ |
char bp_vend[OPT_SIZE]; /* Vendor information */ |
} Bootp_t; |
|
#define BOOTP_HDR_SIZE sizeof (Bootp_t) |
#define BOOTP_SIZE (ETHER_HDR_SIZE + IP_HDR_SIZE + BOOTP_HDR_SIZE) |
|
/**********************************************************************/ |
/* |
* Global functions and variables. |
*/ |
|
/* bootp.c */ |
extern unsigned long BootpID; /* ID of cur BOOTP request */ |
extern char BootFile[128]; /* Boot file name */ |
extern int BootpTry; |
#ifdef CONFIG_BOOTP_RANDOM_DELAY |
unsigned long seed1, seed2; /* seed for random BOOTP delay */ |
#endif |
|
|
/* Send a BOOTP request */ |
extern void BootpRequest (void); |
|
/****************** DHCP Support *********************/ |
extern void DhcpRequest(void); |
|
/* DHCP States */ |
typedef enum { INIT, |
INIT_REBOOT, |
REBOOTING, |
SELECTING, |
REQUESTING, |
REBINDING, |
BOUND, |
RENEWING } dhcp_state_t; |
|
#define DHCP_DISCOVER 1 |
#define DHCP_OFFER 2 |
#define DHCP_REQUEST 3 |
#define DHCP_DECLINE 4 |
#define DHCP_ACK 5 |
#define DHCP_NAK 6 |
#define DHCP_RELEASE 7 |
|
#define SELECT_TIMEOUT 3 /* Seconds to wait for offers */ |
|
/**********************************************************************/ |
|
#endif /* __BOOTP_H__ */ |
/services/rarp.h
0,0 → 1,44
/* |
* (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 |
*/ |
|
|
#ifndef __RARP_H__ |
#define __RARP_H__ |
|
#ifndef __NET_H__ |
#include "net.h" |
#endif /* __NET_H__ */ |
|
|
/**********************************************************************/ |
/* |
* Global functions and variables. |
*/ |
|
extern int RarpTry; |
|
extern void RarpRequest (void); /* Send a RARP request */ |
|
/**********************************************************************/ |
|
#endif /* __RARP_H__ */ |
/services/Makefile
0,0 → 1,44
# (C) Marko Mlinar, based on ppcboot |
# |
# (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 |
# |
|
# CFLAGS += -DET_DEBUG -DDEBUG |
|
LIB = services.o |
|
# OBJS = net.o tftp.o bootp.o rarp.o arp.o |
OBJS = net.o tftp.o bootp.o rarp.o arp.o |
|
all: $(LIB) |
|
$(LIB): $(START) $(OBJS) |
$(LD) -r -o $@ $(OBJS) |
|
######################################################################### |
|
.depend: Makefile $(OBJS:.o=.c) |
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ |
|
sinclude .depend |
|
######################################################################### |
/services/tftp.c
0,0 → 1,326
/* |
* Copyright 1994, 1995, 2000 Neil Russell. |
* (See License) |
* Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de |
*/ |
|
#include "common.h" |
#include "support.h" |
#include "net.h" |
#include "tftp.h" |
#include "bootp.h" |
|
#undef ET_DEBUG |
|
#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ |
#define TIMEOUT 2 /* Seconds to timeout for a lost pkt */ |
#define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ |
/* (for checking the image size) */ |
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ |
|
/* |
* TFTP operations. |
*/ |
#define TFTP_RRQ 1 |
#define TFTP_WRQ 2 |
#define TFTP_DATA 3 |
#define TFTP_ACK 4 |
#define TFTP_ERROR 5 |
|
|
extern unsigned long load_addr; |
|
static int TftpServerPort; /* The UDP port at their end */ |
static int TftpOurPort; /* The UDP port at our end */ |
static int TftpTimeoutCount; |
static unsigned TftpBlock; |
static unsigned TftpLastBlock; |
static int TftpState; |
#define STATE_RRQ 1 |
#define STATE_DATA 2 |
#define STATE_TOO_LARGE 3 |
#define STATE_BAD_MAGIC 4 |
|
#define DEFAULT_NAME_LEN (8 + 4 + 1) |
static char default_filename[DEFAULT_NAME_LEN] = "tftpboot.img"; |
static char *tftp_filename; |
|
#ifdef CFG_DIRECT_FLASH_TFTP |
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; |
#endif |
|
static __inline__ void |
store_block (unsigned block, unsigned char * src, unsigned len) |
{ |
unsigned long offset = block * 512, newsize = offset + len; |
#ifdef CFG_DIRECT_FLASH_TFTP |
int i, rc = 0; |
|
for (i=0; i<CFG_MAX_FLASH_BANKS; i++) { |
/* start address in flash? */ |
if (load_addr + offset >= flash_info[i].start[0]) { |
rc = 1; |
break; |
} |
} |
|
if (rc) { /* Flash is destination for this packet */ |
rc = flash_write ((unsigned char *)src, (unsigned long)(load_addr+offset), len); |
switch (rc) { |
case 0: /* OK */ |
break; |
case 1: printf ("Timeout writing to Flash\n"); |
break; |
case 2: printf ("Flash not Erased\n"); |
break; |
case 4: printf ("Can't write to protected Flash sectors\n"); |
break; |
case 8: printf ("Outside available Flash\n"); |
break; |
case 16:printf ("Size must be aligned (multiple of 8?)\n"); |
break; |
default: |
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); |
break; |
} |
if (rc) { |
NetState = NETLOOP_FAIL; |
return; |
} |
} |
else |
#endif /* CFG_DIRECT_FLASH_TFTP */ |
(void)memcpy((void *)(load_addr + offset), src, len); |
|
if (NetBootFileXferSize < newsize) |
NetBootFileXferSize = newsize; |
} |
|
static void TftpSend (void); |
static void TftpTimeout (void); |
|
/**********************************************************************/ |
|
static void |
TftpSend (void) |
{ |
volatile unsigned char * pkt; |
volatile unsigned char * xp; |
int len = 0; |
|
/* |
* We will always be sending some sort of packet, so |
* cobble together the packet headers now. |
*/ |
pkt = NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE; |
|
switch (TftpState) { |
|
case STATE_RRQ: |
xp = pkt; |
*((unsigned short *)pkt)++ = SWAP16c(TFTP_RRQ); |
strcpy ((char *)pkt, tftp_filename); |
pkt += strlen(tftp_filename) + 1; |
strcpy ((char *)pkt, "octet"); |
pkt += 5 /*strlen("octet")*/ + 1; |
len = pkt - xp; |
break; |
|
case STATE_DATA: |
xp = pkt; |
*((unsigned short *)pkt)++ = SWAP16c(TFTP_ACK); |
*((unsigned short *)pkt)++ = SWAP16(TftpBlock); |
len = pkt - xp; |
break; |
|
case STATE_TOO_LARGE: |
xp = pkt; |
*((unsigned short *)pkt)++ = SWAP16c(TFTP_ERROR); |
*((unsigned short *)pkt)++ = SWAP16(3); |
strcpy ((char *)pkt, "File too large"); |
pkt += 14 /*strlen("File too large")*/ + 1; |
len = pkt - xp; |
break; |
|
case STATE_BAD_MAGIC: |
xp = pkt; |
*((unsigned short *)pkt)++ = SWAP16c(TFTP_ERROR); |
*((unsigned short *)pkt)++ = SWAP16(2); |
strcpy ((char *)pkt, "File has bad magic"); |
pkt += 18 /*strlen("File has bad magic")*/ + 1; |
len = pkt - xp; |
break; |
} |
|
NetSetEther (NetTxPacket, NetServerEther, PROT_IP); |
NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP, |
TftpServerPort, TftpOurPort, len); |
NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); |
} |
|
|
static void |
TftpHandler (unsigned char * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
if (dest != TftpOurPort) { |
return; |
} |
if (TftpState != STATE_RRQ && src != TftpServerPort) { |
return; |
} |
|
if (len < 2) { |
return; |
} |
len -= 2; |
switch (SWAP16(*((unsigned short *)pkt)++)) { |
|
case TFTP_RRQ: |
case TFTP_WRQ: |
case TFTP_ACK: |
break; |
default: |
break; |
|
case TFTP_DATA: |
if (len < 2) |
return; |
len -= 2; |
TftpBlock = SWAP16(*(unsigned short *)pkt); |
if (((TftpBlock - 1) % 10) == 0) { |
putc ('#'); |
} else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) { |
printf ("\n\t "); |
} |
|
if (TftpState == STATE_RRQ) { |
TftpState = STATE_DATA; |
TftpServerPort = src; |
TftpLastBlock = 0; |
|
if (TftpBlock != 1) { /* Assertion */ |
printf ("\nTFTP error: " |
"First block is not block 1 (%d)\n" |
"Starting again\n\n", |
TftpBlock); |
NetStartAgain (); |
break; |
} |
} |
|
if (TftpBlock == TftpLastBlock) { |
/* |
* Same block again; ignore it. |
*/ |
break; |
} |
|
TftpLastBlock = TftpBlock; |
NetSetTimeout (TIMEOUT * IN_CLK, TftpTimeout); |
|
store_block (TftpBlock - 1, pkt + 2, len); |
|
/* |
* Acknoledge the block just received, which will prompt |
* the server for the next one. |
*/ |
TftpSend (); |
|
if (len < 512) { |
/* |
* We received the whole thing. Try to |
* run it. |
*/ |
printf ("\ndone\n"); |
NetState = NETLOOP_SUCCESS; |
} |
break; |
|
case TFTP_ERROR: |
printf ("\nTFTP error: '%s' (%d)\n", |
pkt + 2, SWAP16(*(unsigned short *)pkt)); |
printf ("Starting again\n\n"); |
NetStartAgain (); |
break; |
} |
} |
|
|
static void |
TftpTimeout (void) |
{ |
if (++TftpTimeoutCount >= TIMEOUT_COUNT) { |
printf ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
} else { |
printf ("T "); |
NetSetTimeout (TIMEOUT * IN_CLK, TftpTimeout); |
TftpSend (); |
} |
} |
|
|
void |
TftpStart (void) |
{ |
#ifdef ET_DEBUG |
printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", |
NetServerEther[0], |
NetServerEther[1], |
NetServerEther[2], |
NetServerEther[3], |
NetServerEther[4], |
NetServerEther[5] |
); |
#endif /* DEBUG */ |
|
if (BootFile[0] == '\0') { |
tftp_filename = default_filename; |
|
printf ("*** Warning: no boot file name; using '%s'\n", |
tftp_filename); |
} else { |
tftp_filename = BootFile; |
} |
|
printf ("TFTP from server "); print_IPaddr (NetServerIP); |
printf ("; our IP address is "); print_IPaddr (NetOurIP); |
|
// Check if we need to send across this subnet |
if (NetOurGatewayIP && NetOurSubnetMask) { |
IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; |
IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; |
|
if (OurNet != ServerNet) { |
printf ("; sending through gateway "); |
print_IPaddr (NetOurGatewayIP) ; |
} |
} |
putc ('\n'); |
|
printf ("Filename '%s'.", tftp_filename); |
|
if (NetBootFileSize) { |
printf (" Size is %d%s kB => %x Bytes", |
NetBootFileSize/2, |
(NetBootFileSize%2) ? ".5" : "", |
NetBootFileSize<<9); |
} |
|
putc ('\n'); |
|
printf ("Load address: 0x%lx\n", load_addr); |
|
printf ("Loading: *\b"); |
|
NetSetTimeout (TIMEOUT * IN_CLK, TftpTimeout); |
NetSetHandler (TftpHandler); |
|
TftpServerPort = WELL_KNOWN_PORT; |
TftpTimeoutCount = 0; |
TftpState = STATE_RRQ; |
TftpOurPort = 1024 + (get_timer(0) % 3072); |
|
TftpSend (); |
} |
|
/mc.h
0,0 → 1,111
/* mc.h -- Simulation of Memory Controller |
Copyright (C) 2001 by Marko Mlinar, markom@opencores.org |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
/* Prototypes */ |
#ifndef __MC_H |
#define __MC_H |
|
#define N_CE (8) |
|
#define MC_CSR (0x00) |
#define MC_POC (0x04) |
#define MC_BA_MASK (0x08) |
#define MC_CSC(i) (0x10 + (i) * 8) |
#define MC_TMS(i) (0x14 + (i) * 8) |
|
#define MC_ADDR_SPACE (MC_CSC(N_CE)) |
|
/* POC register field definition */ |
#define MC_POC_EN_BW_OFFSET 0 |
#define MC_POC_EN_BW_WIDTH 2 |
#define MC_POC_EN_MEMTYPE_OFFSET 2 |
#define MC_POC_EN_MEMTYPE_WIDTH 2 |
|
/* CSC register field definition */ |
#define MC_CSC_EN_OFFSET 0 |
#define MC_CSC_MEMTYPE_OFFSET 1 |
#define MC_CSC_MEMTYPE_WIDTH 2 |
#define MC_CSC_BW_OFFSET 4 |
#define MC_CSC_BW_WIDTH 2 |
#define MC_CSC_MS_OFFSET 6 |
#define MC_CSC_MS_WIDTH 2 |
#define MC_CSC_WP_OFFSET 8 |
#define MC_CSC_BAS_OFFSET 9 |
#define MC_CSC_KRO_OFFSET 10 |
#define MC_CSC_PEN_OFFSET 11 |
#define MC_CSC_SEL_OFFSET 16 |
#define MC_CSC_SEL_WIDTH 8 |
|
#define MC_CSC_MEMTYPE_SDRAM 0 |
#define MC_CSC_MEMTYPE_SSRAM 1 |
#define MC_CSC_MEMTYPE_ASYNC 2 |
#define MC_CSC_MEMTYPE_SYNC 3 |
|
#define MC_CSR_VALID 0xFF000703LU |
#define MC_POC_VALID 0x0000000FLU |
#define MC_BA_MASK_VALID 0x000000FFLU |
#define MC_CSC_VALID 0x00FF0FFFLU |
#define MC_TMS_SDRAM_VALID 0x0FFF83FFLU |
#define MC_TMS_SSRAM_VALID 0x00000000LU |
#define MC_TMS_ASYNC_VALID 0x03FFFFFFLU |
#define MC_TMS_SYNC_VALID 0x01FFFFFFLU |
#define MC_TMS_VALID 0xFFFFFFFFLU /* reg test compat. */ |
|
/* TMS register field definition SDRAM */ |
#define MC_TMS_SDRAM_TRFC_OFFSET 24 |
#define MC_TMS_SDRAM_TRFC_WIDTH 4 |
#define MC_TMS_SDRAM_TRP_OFFSET 20 |
#define MC_TMS_SDRAM_TRP_WIDTH 4 |
#define MC_TMS_SDRAM_TRCD_OFFSET 17 |
#define MC_TMS_SDRAM_TRCD_WIDTH 4 |
#define MC_TMS_SDRAM_TWR_OFFSET 15 |
#define MC_TMS_SDRAM_TWR_WIDTH 2 |
#define MC_TMS_SDRAM_WBL_OFFSET 9 |
#define MC_TMS_SDRAM_OM_OFFSET 7 |
#define MC_TMS_SDRAM_OM_WIDTH 2 |
#define MC_TMS_SDRAM_CL_OFFSET 4 |
#define MC_TMS_SDRAM_CL_WIDTH 3 |
#define MC_TMS_SDRAM_BT_OFFSET 3 |
#define MC_TMS_SDRAM_BL_OFFSET 0 |
#define MC_TMS_SDRAM_BL_WIDTH 3 |
|
/* TMS register field definition ASYNC */ |
#define MC_TMS_ASYNC_TWWD_OFFSET 20 |
#define MC_TMS_ASYNC_TWWD_WIDTH 6 |
#define MC_TMS_ASYNC_TWD_OFFSET 16 |
#define MC_TMS_ASYNC_TWD_WIDTH 4 |
#define MC_TMS_ASYNC_TWPW_OFFSET 12 |
#define MC_TMS_ASYNC_TWPW_WIDTH 4 |
#define MC_TMS_ASYNC_TRDZ_OFFSET 8 |
#define MC_TMS_ASYNC_TRDZ_WIDTH 4 |
#define MC_TMS_ASYNC_TRDV_OFFSET 0 |
#define MC_TMS_ASYNC_TRDV_WIDTH 8 |
|
/* TMS register field definition SYNC */ |
#define MC_TMS_SYNC_TTO_OFFSET 16 |
#define MC_TMS_SYNC_TTO_WIDTH 9 |
#define MC_TMS_SYNC_TWR_OFFSET 12 |
#define MC_TMS_SYNC_TWR_WIDTH 4 |
#define MC_TMS_SYNC_TRDZ_OFFSET 8 |
#define MC_TMS_SYNC_TRDZ_WIDTH 4 |
#define MC_TMS_SYNC_TRDV_OFFSET 0 |
#define MC_TMS_SYNC_TRDV_WIDTH 8 |
|
#endif |
/sim.cfg
0,0 → 1,765
/* sim.cfg -- Simulator configuration script file |
Copyright (C) 2001, Marko Mlinar, markom@opencores.org |
|
This file includes a lot of help about configurations and default one |
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
|
/* INTRODUCTION |
|
The or1ksim have various parameters, which can be set in configuration |
files. Multiple configurations may be used and switched between at |
or1ksim startup. |
By default, or1ksim loads condfiguration file from './sim.cfg' and if not |
found it checks '~/.or1k/sim.cfg'. If even this file is not found or |
all parameters are not defined, default configuration is used. |
Users should not rely on default configuration, but rather redefine all |
critical settings, since default configuration may differ in newer |
versions of the or1ksim. |
If multiple configurations are used, user can switch between them by |
supplying -f <filename.cfg> option when starting simulator. |
|
This file may contain (standard C) only comments - no // support. |
|
Configure files can also be included, using: |
|
include "file_name_to_include" |
|
Like normal configuration file, this file is divided in sections, |
where each section is described in detail also. |
|
Some section also have subsections. One example of such subsection is |
block: |
|
device <index> |
instance specific parameters... |
enddevice |
|
which creates a device instance. |
*/ |
|
/* MEMORY SECTION |
|
This section specifies how is initial memory generated and which blocks |
it consist of. |
|
type = random/unknown/pattern |
specifies the initial memory values. 'random' parameter generate |
random memory using seed 'random_seed' parameter. 'pattern' parameter |
fills memory with 'pattern' parameter and 'unknown' does not specify |
how memory should be generated - the fastest option. |
|
random_seed = <value> |
random seed for randomizer, used if type = random |
|
pattern = <value> |
pattern to fill memory, used if type = pattern |
|
nmemories = <value> |
number of memory instances connected |
|
instance specific: |
baseaddr = <hex_value> |
memory start address |
|
size = <hex_value> |
memory size |
|
name = "<string>" |
memory block name |
|
ce = <value> |
chip enable index of the memory instance |
|
delayr = <value> |
cycles, required for read access, -1 if instance does not support reading |
|
delayw = <value> |
cycles, required for write access, -1 if instance does not support writing |
|
16550 = 0/1 |
0, if this device is uart 16450 and 1, if it is 16550 |
|
log = "<filename>" |
filename, where to log memory accesses to, no log, if log command is not specified |
*/ |
|
section memory |
/*random_seed = 12345 |
type = random*/ |
pattern = 0x00 |
type = unknown /* Fastest */ |
|
nmemories = 2 |
device 0 |
name = "FLASH" |
ce = 0 |
baseaddr = 0x04000000 |
size = 0x00200000 |
delayr = 10 |
delayw = -1 |
enddevice |
|
device 1 |
name = "RAM" |
ce = 1 |
baseaddr = 0x00000000 |
size = 0x00200000 |
delayr = 2 |
delayw = 4 |
enddevice |
end |
|
|
/* IMMU SECTION |
|
This section configures Instruction Memory Menangement Unit |
|
enabled = 0/1 |
whether IMMU is enabled |
(NOTE: UPR bit is set) |
|
nsets = <value> |
number of ITLB sets; must be power of two |
|
nways = <value> |
number of ITLB ways |
|
pagesize = <value> |
instruction page size; must be power of two |
|
entrysize = <value> |
instruction entry size in bytes |
|
ustates = <value> |
number of ITLB usage states (2, 3, 4 etc., max is 4) |
|
hitdelay = <value> |
number of cycles immu hit costs |
|
missdelay = <value> |
number of cycles immu miss costs |
*/ |
|
section immu |
enabled = 0 |
nsets = 32 |
nways = 1 |
pagesize = 8192 |
hitdelay = 0 |
missdelay = 0 |
end |
|
|
/* DMMU SECTION |
|
This section configures Data Memory Menangement Unit |
|
enabled = 0/1 |
whether DMMU is enabled |
(NOTE: UPR bit is set) |
|
nsets = <value> |
number of DTLB sets; must be power of two |
|
nways = <value> |
number of DTLB ways |
|
pagesize = <value> |
data page size; must be power of two |
|
entrysize = <value> |
data entry size in bytes |
|
ustates = <value> |
number of DTLB usage states (2, 3, 4 etc., max is 4) |
|
hitdelay = <value> |
number of cycles immu hit costs |
|
missdelay = <value> |
number of cycles immu miss costs |
*/ |
|
section dmmu |
enabled = 0 |
nsets = 32 |
nways = 1 |
pagesize = 8192 |
hitdelay = 0 |
missdelay = 0 |
end |
|
|
/* IC SECTION |
|
This section configures Instruction Cache |
|
enabled = 0/1 |
whether IC is enabled |
(NOTE: UPR bit is set) |
|
nsets = <value> |
number of IC sets; must be power of two |
|
nways = <value> |
number of IC ways |
|
blocksize = <value> |
IC block size in bytes; must be power of two |
|
ustates = <value> |
number of IC usage states (2, 3, 4 etc., max is 4) |
|
hitdelay = <value> |
number of cycles ic hit costs |
|
missdelay = <value> |
number of cycles ic miss costs |
*/ |
|
section ic |
enabled = 0 |
nsets = 512 |
nways = 1 |
blocksize = 16 |
hitdelay = 0 |
missdelay = 0 |
end |
|
|
/* DC SECTION |
|
This section configures Data Cache |
|
enabled = 0/1 |
whether DC is enabled |
(NOTE: UPR bit is set) |
|
nsets = <value> |
number of DC sets; must be power of two |
|
nways = <value> |
number of DC ways |
|
blocksize = <value> |
DC block size in bytes; must be power of two |
|
ustates = <value> |
number of DC usage states (2, 3, 4 etc., max is 4) |
|
load_hitdelay = <value> |
number of cycles dc load hit costs |
|
load_missdelay = <value> |
number of cycles dc load miss costs |
|
store_hitdelay = <value> |
number of cycles dc load hit costs |
|
store_missdelay = <value> |
number of cycles dc load miss costs |
*/ |
|
section dc |
enabled = 0 |
nsets = 512 |
nways = 1 |
blocksize = 16 |
load_hitdelay = 0 |
load_missdelay = 0 |
store_hitdelay = 0 |
store_missdelay = 0 |
end |
|
/* SIM SECTION |
|
This section specifies how should sim behave. |
|
verbose = 0/1 |
whether to print out extra messages |
|
debug = 0-9 |
= 0 disabled debug messages |
1-9 level of sim debug information, greater the number more verbose is |
the output |
|
profile = 0/1 |
whether to generate profiling file 'sim.profile' |
|
prof_fn = "<filename>" |
filename, where to generate profiling info, used |
only if 'profile' is set |
|
mprofile = 0/1 |
whether to generate memory profiling file 'sim.mprofile' |
|
mprof_fn = "<filename>" |
filename, where to generate memory profiling info, used |
only if 'mprofile' is set |
|
history = 0/1 |
whether instruction execution flow is tracked for |
display by simulator hist command. Useful for |
back-trace debugging. |
|
iprompt = 0/1 |
whether we strart in interactive prompt |
|
exe_log = 0/1 |
whether execution log should be generated |
|
exe_log = default/hardware/simple/software |
type of executed log, default is used if not specified |
|
exe_log_start = <value> |
index of first instruction to start log with, default = 0 |
|
exe_log_end = <value> |
index of last instruction to end log with; not limited, if omitted |
|
exe_log_marker = <value> |
<value> specifies number of instructions before horizontal marker is |
printed; if zero, markers are disabled (default) |
|
exe_log_fn = "<filename>" |
where to put execution log in, used only if 'exe_log' |
is set |
|
spr_log = 0/1 |
whether log of writes/reads to/from sprs should be generated |
|
spr_log_fn = "<filename>" |
where to put sprs writes/reads in log, used only if 'spr_log' |
is set |
|
clkcycle = <value>[ps|ns|us|ms] |
specifies time measurement for one cycle |
*/ |
|
section sim |
/* verbose = 1 */ |
debug = 3 |
profile = 0 |
prof_fn = "sim.profile" |
mprofile = 0 |
mprof_fn = "sim.mprofile" |
|
history = 0 |
/* iprompt = 0 */ |
exe_log = 0 |
exe_log_type = software |
exe_log_fn = "executed.log" |
spr_log = 0 |
spr_log_fn = "spr.log" |
clkcycle = 100ns |
end |
|
|
/* SECTION VAPI |
|
This section configures Verification API, used for Advanced |
Core Verification. |
|
enabled = 0/1 |
whether to start VAPI server |
|
server_port = <value> |
TCP/IP port to start VAPI server on |
|
log_enabled = 0/1 |
whether logging of VAPI requests is enabled |
|
hide_device_id = 0/1 |
whether to disable logging of device id (for compatability with old version) |
|
vapi_fn = <filename> |
specifies filename where to log into, if log_enabled is selected |
*/ |
|
section VAPI |
enabled = 0 |
server_port = 9998 |
log_enabled = 0 |
vapi_log_fn = "vapi.log" |
end |
|
|
/* CPU SECTION |
|
This section specifies various CPU parameters. |
|
ver = <value> |
rev = <value> |
specifies version and revision of the CPU used |
|
upr = <value> |
changes the upr register |
|
sr = <value> |
sets the initial Supervision Register value |
|
superscalar = 0/1 |
whether CPU is scalar or superscalar |
(modify cpu/or32/execute.c to tune superscalar model) |
|
hazards = 0/1 |
whether data hazards are tracked in superscalar CPU |
and displayed by the simulator r command |
|
dependstats = 0/1 |
whether inter-instruction dependencies are calculated |
and displayed by simulator stats command. |
|
sbuf_len = <value> |
length of store buffer (<= 256), 0 = disabled |
*/ |
|
section cpu |
ver = 0x1200 |
rev = 0x0001 |
/* upr = */ |
sr = 0x00008003 |
superscalar = 0 |
hazards = 0 |
dependstats = 0 |
sbuf_len = 0 |
end |
|
|
/* PM SECTION |
|
This section specifies Power Menagement paramaters |
|
enabled = 0/1 |
whether power menagement is enabled |
*/ |
|
section pm |
enabled = 0 |
end |
|
/* BPB SECTION |
|
This section specifies how branch prediction should behave. |
|
enabled = 0/1 |
whether bpb is enabled |
|
btic = 0/1 |
enable branch target instruction cache model |
|
sbp_bf_fwd = 0/1 |
whether static branch prediction for l.bf uses forward prediction |
|
sbp_bnf_fwd = 0/1 |
whether static branch prediction for l.bnf uses forward prediction |
|
hitdelay = <value> |
number of cycles bpb hit costs |
|
missdelay = <value> |
number of cycles bpb miss costs |
*/ |
|
section bpb |
enabled = 0 |
btic = 0 |
sbp_bf_fwd = 0 |
sbp_bnf_fwd = 0 |
hitdelay = 0 |
missdelay = 0 |
end |
|
|
/* DEBUG SECTION |
|
This sections specifies how debug unit should behave. |
|
enabled = 0/1 |
whether debug unit is enabled |
|
gdb_enabled = 0/1 |
whether to start gdb server at 'server_port' port |
|
server_port = <value> |
TCP/IP port to start gdb server on, used only if gdb_enabled |
is set |
|
vapi_id = <hex_value> |
Used to create "fake" vapi log file containing the JTAG proxy messages. |
*/ |
|
section debug |
enabled = 1 |
gdb_enabled = 0 |
server_port = 9999 |
vapi_id = 0xFFFF |
end |
|
|
/* MC SECTION |
|
This section configures the memory controller |
|
enabled = 0/1 |
whether memory controller is enabled |
|
baseaddr = <hex_value> |
address of first MC register |
|
POC = <hex_value> |
Power On Configuration register |
*/ |
|
section mc |
enabled = 1 |
baseaddr = 0x60000000 |
POC = 0x00000008 /* Power on configuration register */ |
end |
|
|
/* UART SECTION |
|
This section configures UARTs |
|
nuarts = <value> |
make specified number of instances, configure each |
instance within device - enddevice construct. |
|
instance specific: |
baseaddr = <hex_value> |
address of first UART register for this device |
|
rxfile = "<filename>" |
filename, where to read data from |
|
txfile = "<filename>" |
filename, where to write data to |
|
irq = <value> |
irq number for this device |
|
16550 = 0/1 |
0, if this device is uart 16450 and 1, if it is 16550 |
|
jitter = <value> |
in msecs... time to block, -1 to disable it |
|
vapi_id = <hex_value> |
VAPI id of this instance |
*/ |
|
section uart |
nuarts = 1 |
|
device 0 |
baseaddr = 0x90000000 |
irq = 2 |
rxfile = "uart0.rx" |
txfile = "uart0.tx" |
jitter = -1 /* async behaviour */ |
enddevice |
end |
|
|
/* DMA SECTION |
|
This section configures DMAs |
|
ndmas = <value> |
make specified number of instances, configure each |
instance within device - enddevice construct. |
|
instance specific: |
baseaddr = <hex_value> |
address of first DMA register for this device |
|
irq = <value> |
irq number for this device |
|
vapi_id = <hex_value> |
VAPI id of this instance |
*/ |
|
section dma |
ndmas = 0 |
/* |
device 0 |
baseaddr = 0x90000000 |
irq = 4 |
enddevice |
*/ |
end |
|
|
/* ETHERNET SECTION |
|
This section configures ethernets |
|
nethernets = <value> |
make specified number of instances, configure each |
instance within device - enddevice construct. |
|
instance specific: |
baseaddr = <hex_value> |
address of first ethernet register for this device |
|
dma = <value> |
which controller is this ethernet "connected" to |
|
rx_channel = <value> |
DMA channel used for RX |
|
tx_channel = <value> |
DMA channel used for TX |
|
rxfile = "<filename>" |
filename, where to read data from |
|
txfile = "<filename>" |
filename, where to write data to |
|
vapi_id = <hex_value> |
VAPI id of this instance |
*/ |
|
section ethernet |
nethernets = 1 |
|
|
device 0 |
baseaddr = 0xD0000000 |
dma = 0 |
tx_channel = 0 |
rx_channel = 1 |
rxfile = "/tmp/eth0.rx" |
txfile = "/tmp/eth0.tx" |
enddevice |
|
end |
|
/* GPIO SECTION |
|
This section configure GPIOs |
|
ngpios = <value> |
make specified number of instances, configure each |
instance within device - enddevice construct. |
|
instance specific: |
baseaddr = <hex_value> |
address of first GPIO register for this device |
|
irq = <value> |
irq number for this device |
|
base_vapi_id = <hex_value> |
first VAPI id of this instance |
GPIO uses 8 consecutive VAPI IDs |
*/ |
|
section gpio |
ngpios = 1 |
|
device 0 |
baseaddr = 0xA0000000 |
irq = 23 |
base_vapi_id = 0x0200 |
enddevice |
end |
|
/* VGA SECTION |
|
This section configures VGA/LCD controller |
|
nvgas = <value> |
number of VGA devices connected |
|
instance specific: |
baseaddr = <hex_value> |
address of first VGA register |
|
irq = <value> |
irq number for this device |
|
refresh_rate = <value> |
number of cycles between screen dumps |
|
filename = "<filename>" |
template name for generated names (e.g. "primary" produces "primary0023.bmp") |
*/ |
/* |
section vga |
nvgas = 1 |
|
device 0 |
baseaddr = 0xb0000000 |
irq = 20 |
refresh_rate = 100000 |
filename = "primary" |
enddevice |
end |
*/ |
/* FB SECTION |
|
This section configures frame buffer |
|
enabled = 0/1 |
whether frame buffer is enabled |
|
baseaddr = <hex_value> |
base address of frame buffer |
|
paladdr = <hex_value> |
base address of first palette entry |
|
refresh_rate = <value> |
number of cycles between screen dumps |
|
filename = "<filename>" |
template name for generated names (e.g. "primary" produces "primary0023.bmp") |
*/ |
|
section fb |
enabled = 1 |
baseaddr = 0xb8000000 |
refresh_rate = 100000 |
filename = "primary" |
end |
|
/* KBD SECTION |
|
This section configures PS/2 compatible keyboard |
|
enabled = 0/1 |
whether keyboard is enabled |
|
baseaddr = <hex_value> |
base address of the keyboard device |
|
rxfile = "<filename>" |
filename, where to read data from |
*/ |
|
section kbd |
enabled = 1 |
irq = 21 |
baseaddr = 0xb1000000 |
rxfile = "/tmp/kbd.rx" |
end |
/cmds/eth.c
0,0 → 1,362
#include "common.h" |
#include "uart.h" |
#include "eth.h" |
#include "spr_defs.h" |
|
extern int tx_pointer_index; |
unsigned long dest_mac_addr[6]; |
|
#if 0 |
void show_tx_bd(int start, int max) |
{ |
int cnt, i; |
|
for(i = start; i <= max; i++) { |
/* Read Tx BD */ |
printf ("LEN:%04", REG32(ETH_BD_BASE + (i << 3)) >> 16); |
printf (" RD:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 15) & 0x1); |
printf (" IRQ:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 14) & 0x1); |
printf (" WR:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 13) & 0x1); |
printf (" PAD:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 12) & 0x1); |
printf (" CRC:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 11) & 0x1); |
printf (" UR:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 8) & 0x1); |
printf (" RTRY:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 4) & 0xf); |
printf (" RL:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 3) & 0x1); |
printf (" LC:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 2) & 0x1); |
printf (" DF:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 1) & 0x1); |
printf (" CS:%04", (REG32(ETH_BD_BASE + (i << 3)) >> 0) & 0x1); |
printf ("\nTx Buffer Pointer: %08x\n", REG32(ETH_BD_BASE + (i << 3) + 4)); |
} |
} |
|
void show_rx_bd (int start, int max) |
{ |
int cnt, i; |
unsigned long rx_bd_base, rx_bd_num; |
|
rx_bd_num = REG32(ETH_REG_BASE + ETH_RXBD_NUM); |
rx_bd_base = ETH_BD_BASE + (rx_bd_num << 2); |
|
for(i = start; i <= max; i++){ |
/* Read Rx BD */ |
printf ("LEN:%04", REG32(rx_bd_base + (i << 3)) >> 16); |
printf (" E:%04", (REG32(rx_bd_base + (i << 3)) >> 15) & 0x1); |
printf (" IRQ:%04", (REG32(rx_bd_base + (i << 3)) >> 14) & 0x1); |
printf (" WR:%04", (REG32(rx_bd_base + (i << 3)) >> 13) & 0x1); |
printf (" M:%04", (REG32(rx_bd_base + (i << 3)) >> 7) & 0x1); |
printf (" OR:%04", (REG32(rx_bd_base + (i << 3)) >> 6) & 0x1); |
printf (" IS:%04", (REG32(rx_bd_base + (i << 3)) >> 5) & 0x1); |
printf (" DN:%04", (REG32(rx_bd_base + (i << 3)) >> 4) & 0x1); |
printf (" TL:%04", (REG32(rx_bd_base + (i << 3)) >> 3) & 0x1); |
printf (" SF:%04", (REG32(rx_bd_base + (i << 3)) >> 2) & 0x1); |
printf (" CRC:%04", (REG32(rx_bd_base + (i << 3)) >> 1) & 0x1); |
printf (" LC:%04", (REG32(rx_bd_base + (i << 3)) >> 0) & 0x1); |
printf ("\nRx Buffer Pointer: %08x\n", REG32(rx_bd_base + (i << 3) + 4)); |
} |
} |
|
void show_buffer(unsigned long start_addr, unsigned long len) |
{ |
show_mem(start_addr, start_addr + len - 1); |
} |
|
void show_rx_buffs(int max, int show_all) |
{ |
|
int i; |
unsigned long rx_bd_base, rx_bd_num; |
|
rx_bd_num = REG32(ETH_REG_BASE + ETH_RXBD_NUM); |
rx_bd_base = ETH_BD_BASE + (rx_bd_num << 2); |
|
for(i=0; i<=max; i++) |
{ |
if (!(REG32(rx_bd_base + (i << 3)) & ETH_RX_BD_EMPTY) || show_all) |
{ |
printf ("Rx BD No. %04x located at %08x\n", i, rx_bd_base + (i << 3)); |
show_rx_bd(i, i); |
show_buffer(REG32(rx_bd_base + (i << 3) + 4), REG32(rx_bd_base + (i << 3)) >> 16); |
printf ("\n"); |
} |
if (REG32(rx_bd_base + (i << 3)) & ETH_RX_BD_WRAP) |
return; |
} |
} |
|
void show_tx_buffs(int max) |
{ |
|
int i; |
|
for(i=0; i<=max; i++) |
{ |
if (1) |
{ |
printf ("Tx BD No. %04x located at %08x\n", i, ETH_BD_BASE + (i << 3)); |
show_tx_bd(i, i); |
show_buffer(REG32(ETH_BD_BASE + (i << 3) + 4), REG32(ETH_BD_BASE + (i << 3)) >> 16); |
printf ("\n"); |
} |
if (REG32(ETH_BD_BASE + (i << 3)) & ETH_TX_BD_WRAP) |
return; |
} |
} |
|
void show_phy_reg (unsigned long start_addr, unsigned long stop_addr) |
{ |
|
unsigned long addr; |
|
if (start_addr == stop_addr) |
{ |
printf ("\nSet MII RGAD ADDRESS to %08x", start_addr); |
printf ("\nMII Command = Read Status\n"); |
} |
|
for (addr = start_addr; addr <= stop_addr; addr++) |
{ |
REG32(ETH_REG_BASE + ETH_MIIADDRESS) = addr<<8; |
REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_RSTAT; |
|
printf ("PHY %04x", REG32(ETH_REG_BASE + ETH_MIIADDRESS) & 0x1f); |
printf (", addr %04x", REG32(ETH_REG_BASE + ETH_MIIADDRESS) >> 8); |
printf (": %08x\n", REG32(ETH_REG_BASE + ETH_MIIRX_DATA)); |
} |
} |
|
void set_phy_reg (unsigned long addr, unsigned long val) |
{ |
printf ("\nSet MII RGAD ADDRESS to %08x", addr); |
|
REG32(ETH_REG_BASE + ETH_MIIADDRESS) = addr<<8; |
|
printf ("\nMII Command = Write Control Data\n"); |
REG32(ETH_REG_BASE + ETH_MIICOMMAND) = ETH_MIICOMMAND_WCTRLDATA; |
|
REG32(ETH_REG_BASE + ETH_MIITX_DATA) = val; |
|
show_phy_reg(addr, addr); |
} |
|
void send_packet (unsigned long len, unsigned long start_data, int num_of_packets) |
{ |
unsigned long i, TxBD; |
|
while (num_of_packets--) { |
unsigned long *data = (unsigned long *)eth_get_tx_buf (); |
|
/* Set dest & src address */ |
*data++ = dest_mac_addr[0] << 24 | |
dest_mac_addr[1] << 16 | |
dest_mac_addr[2] << 8 | |
dest_mac_addr[3] << 0; |
|
*data++ = dest_mac_addr[4] << 24 | |
dest_mac_addr[5] << 16 | |
ETH_MACADDR0 << 8 | |
ETH_MACADDR1 << 0; |
|
*data++ = ETH_MACADDR2 << 24 | |
ETH_MACADDR3 << 16 | |
ETH_MACADDR4 << 8 | |
ETH_MACADDR5 << 0; |
|
/* Write data to buffer */ |
for(i = 12; i < len; i += 4) |
*data++ = (i + start_data - 12) << 24 | (i + start_data + 1 - 12) << 16 | |
(i + start_data + 2 - 12) << 8 | (i + start_data + 3 - 12); |
|
eth_send (data, len); |
printf ("."); |
} |
} |
|
int eth_init_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
eth_init (0); |
return 0; |
} |
|
int show_txbd_cmd (int argc, char *argv[]) |
{ |
int cnt, i; |
int start, max; |
|
if (argc == 1) show_tx_bd (strtoul (argv[0]), strtoul (argv[0])); |
else if (argc == 2) show_tx_bd (strtoul (argv[0]), strtoul (argv[1])); |
else show_tx_bd (0, 63); |
return 0; |
} |
|
int show_rxbd_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) show_rx_bd (strtoul (argv[0]), strtoul (argv[0])); |
else if (argc == 2) show_rx_bd (strtoul (argv[0]), strtoul (argv[1])); |
else show_rx_bd (0, 63); |
return 0; |
} |
|
int send_packet_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) send_packet(strtoul (argv[0]), 31, 1); |
else if (argc == 2) send_packet(strtoul (argv[0]), strtoul (argv[1]), 1); |
else if (argc == 3) send_packet(strtoul (argv[0]), strtoul (argv[1]), strtoul (argv[2])); |
else return -1; |
return 0; |
} |
|
int set_dest_addr_cmd (int argc, char *argv[]) |
{ |
if (argc == 3) { |
dest_mac_addr[0] = (strtoul (argv[0]) >> 8) & 0xff; |
dest_mac_addr[1] = (strtoul (argv[0]) >> 0) & 0xff; |
dest_mac_addr[2] = (strtoul (argv[1]) >> 8) & 0xff; |
dest_mac_addr[3] = (strtoul (argv[1]) >> 0) & 0xff; |
dest_mac_addr[4] = (strtoul (argv[2]) >> 8) & 0xff; |
dest_mac_addr[5] = (strtoul (argv[2]) >> 0) & 0xff; |
} else return -1; |
return 0; |
} |
|
int init_txbd_pool_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) init_tx_bd_pool(strtoul (argv[0])); |
else return -1; |
return 0; |
} |
|
int init_rxbd_pool_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) init_rx_bd_pool(strtoul (argv[0])); |
else return -1; |
return 0; |
} |
|
int show_phy_reg_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) show_phy_reg(strtoul (argv[0]), strtoul (argv[0])); |
else if (argc == 2) show_phy_reg(strtoul (argv[0]), strtoul (argv[1])); |
else show_phy_reg(0, 30); |
return 0; |
} |
|
int set_phy_reg_cmd (int argc, char *argv[]) |
{ |
if (argc == 2) set_phy_reg(strtoul (argv[0]), strtoul (argv[1])); |
else return -1; |
return 0; |
} |
|
int show_mac_regs_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
printf ("\n %08x", ETH_REG_BASE + ETH_MODER); |
printf (" MODER: %08x",REG32(ETH_REG_BASE + ETH_MODER)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_INT); |
printf (" INT: %08x", REG32(ETH_REG_BASE + ETH_INT)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_INT_MASK); |
printf (" INT_MASK: %08x", REG32(ETH_REG_BASE + ETH_INT_MASK)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_IPGT); |
printf (" IPGT: %08x", REG32(ETH_REG_BASE + ETH_IPGT)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_IPGR1); |
printf (" IPGR1: %08x", REG32(ETH_REG_BASE + ETH_IPGR1)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_IPGR2); |
printf (" IPGR2: %08x", REG32(ETH_REG_BASE + ETH_IPGR2)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_PACKETLEN); |
printf (" PACKETLEN: %08x", REG32(ETH_REG_BASE + ETH_PACKETLEN)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_COLLCONF); |
printf (" COLLCONF: %08x", REG32(ETH_REG_BASE + ETH_COLLCONF)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_RXBD_NUM); |
printf (" RX_BD_NUM: %08x", REG32(ETH_REG_BASE + ETH_RXBD_NUM)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_CTRLMODER); |
printf (" CTRLMODER: %08x", REG32(ETH_REG_BASE + ETH_CTRLMODER)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIIMODER); |
printf (" MIIMODER: %08x", REG32(ETH_REG_BASE + ETH_MIIMODER)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIICOMMAND); |
printf (" MIICOMMAND: %08x", REG32(ETH_REG_BASE + ETH_MIICOMMAND)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIIADDRESS); |
printf (" MIIADDRESS: %08x", REG32(ETH_REG_BASE + ETH_MIIADDRESS)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIITX_DATA); |
printf (" MIITX_DATA: %08x", REG32(ETH_REG_BASE + ETH_MIITX_DATA)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIIRX_DATA); |
printf (" MIIRX_DATA: %08x", REG32(ETH_REG_BASE + ETH_MIIRX_DATA)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MIISTATUS); |
printf (" MIISTATUS: %08x", REG32(ETH_REG_BASE + ETH_MIISTATUS)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MAC_ADDR0); |
printf (" MAC_ADDR0: %08x", REG32(ETH_REG_BASE + ETH_MAC_ADDR0)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_MAC_ADDR1); |
printf (" MAC_ADDR1: %08x", REG32(ETH_REG_BASE + ETH_MAC_ADDR1)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_HASH_ADDR0); |
printf (" ETH_HASH_ADDR0: %08x", REG32(ETH_REG_BASE + ETH_HASH_ADDR0)); |
|
printf ("\n %08x", ETH_REG_BASE + ETH_HASH_ADDR1); |
printf (" ETH_HASH_ADDR1: %08x", REG32(ETH_REG_BASE + ETH_HASH_ADDR1)); |
|
printf ("\n"); |
return 0; |
} |
|
int eth_int_enable_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
eth_int_enable (); |
return 0; |
} |
int show_rx_buffs_cmd (int argc, char *argv[]) |
{ |
if (argc == 0) show_rx_buffs(63, 0); |
else if (argc == 1) show_rx_buffs(63, 1); |
else return -1; |
return 0; |
} |
|
int show_tx_buffs_cmd (int argc, char *argv[]) |
{ |
if (argc == 0) show_tx_buffs(63); |
else return -1; |
return 0; |
} |
|
#endif |
void module_eth_init () |
{ |
#if 0 |
register_command ("eth_init", "", "init ethernet", eth_init_cmd); |
register_command ("show_txbd", "[<start BD>] [<max>]", "show Tx buffer desc", show_txbd_cmd); |
register_command ("show_rxbd", "[<start BD>] [<max>]", "show Rx buffer desc", show_rxbd_cmd); |
register_command ("send_packet", "<length> [<start data>] [<num_of_packets>]", "create & send packet(s)", send_packet_cmd); |
register_command ("set_dest_addr", "<addrhi> <addrmid> <addrlo>", "set destination address (for send_packet)", set_dest_addr_cmd); |
register_command ("init_txbd_pool", "<max>", "initialize Tx buffer descriptors", init_txbd_pool_cmd); |
register_command ("init_rxbd_pool", "<max>", "initialize Rx buffer descriptors", init_rxbd_pool_cmd); |
register_command ("show_phy_reg", "[<start_addr>] [<end addr>]", "show PHY registers", show_phy_reg_cmd); |
register_command ("set_phy_reg", "<addr> <value>", "set PHY register", set_phy_reg_cmd); |
register_command ("show_mac_regs", "", "show all MAC registers", show_mac_regs_cmd); |
register_command ("eth_int_enable", "", "enable ethernet interrupt", eth_int_enable_cmd); |
register_command ("show_rx_buffs", "[<show_all>]", "show receive buffers (optional arg will also show empty buffers)", show_rx_buffs_cmd); |
register_command ("show_tx_buffs", "", "show transmit buffers", show_rx_buffs_cmd); |
/* Initialize controller */ |
/* eth_init();*/ |
/* printf ("Ethernet not initialized (run eth_init command)\n");*/ |
/* init_rx_bd_pool(0); */ |
/* init_tx_bd_pool(3);*/ |
#endif |
} |
/cmds/global.c
0,0 → 1,57
#include "common.h" |
|
global_struct global; |
|
int src_addr_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) { |
global.src_addr = strtoul (argv[0]); |
return 0; |
} else return -1; |
} |
|
int dst_addr_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) { |
global.dst_addr = strtoul (argv[0]); |
return 0; |
} else return -1; |
} |
|
int length_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) { |
global.length = strtoul (argv[0]); |
return 0; |
} else return -1; |
} |
|
int ip_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) { |
global.ip = strtoul (argv[0]); |
return 0; |
} else return -1; |
} |
|
#if HELP_ENABLED |
int globals_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
printf ("src_addr = %08lx\n", global.src_addr); |
printf ("dst_addr = %08lx\n", global.dst_addr); |
printf ("length = %08lx\n", global.length); |
printf ("ip = %08lx\n", global.ip); |
return 0; |
} |
#endif /* HELP_ENABLED */ |
|
void module_global_init (void) |
{ |
register_command ("src_addr", "<value>", "sets global parameter source address", src_addr_cmd); |
register_command ("dst_addr", "<value>", "sets global parameter destination address", dst_addr_cmd); |
register_command ("length", "<value>", "sets global parameter length", length_cmd); |
register_command ("ip", "<value>", "sets global parameter ip address", ip_cmd); |
if (HELP_ENABLED) register_command ("globals", "", "show globals", globals_cmd); |
} |
|
/cmds/dhry.c
0,0 → 1,708
/* |
**************************************************************************** |
* |
* "DHRYSTONE" Benchmark Program |
* ----------------------------- |
* |
* Version: C, Version 2.1 |
* |
* File: dhry_1.c (part 2 of 3) |
* |
* Date: May 25, 1988 |
* |
* Author: Reinhold P. Weicker |
* |
**************************************************************************** |
*/ |
#include "dhry.h" |
#include "spr_defs.h" |
#include "common.h" |
#include "support.h" |
|
#define DLX_FREQ 200 /* in MHz */ |
#define PROC_6 0 |
|
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) |
#define UNALIGNED(X, Y) \ |
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) |
|
void start_timer(void) |
{ |
unsigned long val; |
|
val = SPR_TTMR_SR | 0x0fffffff; |
asm("l.mtspr r0,%0,%1": : "r" (val), "i" (SPR_TTMR)); |
val = 0; |
asm("l.mtspr r0,%0,%1": : "r" (val), "i" (SPR_TTCR)); |
} |
|
unsigned long read_timer(void) |
{ |
unsigned long val; |
|
asm("l.mfspr %0,r0,%1": "=r" (val) : "i" (SPR_TTCR)); |
return val; |
} |
|
/* Global Variables: */ |
|
Rec_Pointer Ptr_Glob, |
Next_Ptr_Glob; |
int Int_Glob; |
Boolean Bool_Glob; |
char Ch_1_Glob, |
Ch_2_Glob; |
int Arr_1_Glob [50]; |
int Arr_2_Glob [50] [50]; |
|
|
/* forward declaration necessary since Enumeration may not simply be int */ |
|
#ifndef REG |
Boolean Reg = false; |
#define REG |
/* REG becomes defined as empty */ |
/* i.e. no register variables */ |
#else |
Boolean Reg = true; |
#endif |
|
/* variables for time measurement: */ |
|
#if DLX || OR1K |
#define Too_Small_Time DLX_FREQ |
#else |
#define Too_Small_Time 1 |
#endif |
|
#define TIMER0 0 |
#define TIMER1 1 |
|
|
|
|
|
unsigned int Begin_Time, |
End_Time, |
User_Time, |
Microseconds, |
Dhrystones_Per_Second; |
|
/* end of variables for time measurement */ |
|
|
void Proc_1(REG Rec_Pointer Ptr_Val_Par); |
void Proc_2(One_Fifty *Int_Par_Ref); |
void Proc_3(Rec_Pointer *Ptr_Ref_Par); |
void Proc_4(void); |
void Proc_5(void); |
void Proc_6( |
Enumeration Enum_Val_Par, |
Enumeration *Enum_Ref_Par); |
void Proc_7( |
One_Fifty Int_1_Par_Val, |
One_Fifty Int_2_Par_Val, |
One_Fifty *Int_Par_Ref); |
void Proc_8( |
Arr_1_Dim Arr_1_Par_Ref, |
Arr_2_Dim Arr_2_Par_Ref, |
int Int_1_Par_Val, |
int Int_2_Par_Val); |
Enumeration Func_1(Capital_Letter Ch_1_Par_Val, |
Capital_Letter Ch_2_Par_Val); |
Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref); |
Boolean Func_3(Enumeration Enum_Par_Val); |
|
int dhry_main (int num_runs) |
/*****/ |
|
/* main program, corresponds to procedures */ |
/* Main and Proc_0 in the Ada version */ |
{ |
#if 0 |
One_Fifty Int_1_Loc; |
REG One_Fifty Int_2_Loc; |
One_Fifty Int_3_Loc; |
REG char Ch_Index; |
Enumeration Enum_Loc; |
Str_30 Str_1_Loc; |
Str_30 Str_2_Loc; |
REG int Run_Index; |
REG int Number_Of_Runs; |
Rec_Type x, y; |
|
/* Initializations */ |
|
Next_Ptr_Glob = (Rec_Pointer) &x; |
Ptr_Glob = (Rec_Pointer) &y; |
|
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; |
Ptr_Glob->Discr = Ident_1; |
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; |
Ptr_Glob->variant.var_1.Int_Comp = 40; |
strcpy (Ptr_Glob->variant.var_1.Str_Comp, |
"DHRYSTONE PROGRAM, SOME STRING"); |
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); |
|
Arr_2_Glob [8][7] = 10; |
/* Was missing in published program. Without this statement, */ |
/* Arr_2_Glob [8][7] would have an undefined value. */ |
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ |
/* overflow may occur for this array element. */ |
|
/* Initalize Data and Instruction Cache */ |
|
|
/* printf ("\n"); |
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); |
printf ("\n"); |
if (Reg) |
{ |
printf ("Program compiled with 'register' attribute\n"); |
printf ("\n"); |
} |
else |
{ |
printf ("Program compiled without 'register' attribute\n"); |
printf ("\n"); |
} |
printf ("Please give the number of runs through the benchmark: "); |
*/ |
{ |
int n; |
/* scanf ("%d", &n); |
*/ |
n = num_runs; |
Number_Of_Runs = n; |
} |
printf ("\n"); |
|
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); |
|
|
/***************/ |
/* Start timer */ |
/***************/ |
|
/* printf("%d", my_test2(Number_Of_Runs));*/ |
start_timer(); |
Begin_Time = read_timer(); |
|
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) |
{ |
|
Proc_5(); |
Proc_4(); |
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ |
Int_1_Loc = 2; |
Int_2_Loc = 3; |
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); |
Enum_Loc = Ident_2; |
|
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc); |
/* Bool_Glob == 1 */ |
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ |
{ |
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; |
/* Int_3_Loc == 7 */ |
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); |
/* Int_3_Loc == 7 */ |
Int_1_Loc += 1; |
} /* while */ |
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ |
#if DBG |
printf("a) Int_1_Loc: %x\n", Int_1_Loc); |
printf("a) Int_2_Loc: %x\n", Int_2_Loc); |
printf("a) Int_3_Loc: %x\n\n", Int_3_Loc); |
#endif |
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); |
/* Int_Glob == 5 */ |
#if DBG |
printf("b) Int_1_Loc: %x\n", Int_1_Loc); |
printf("b) Int_2_Loc: %x\n", Int_2_Loc); |
printf("b) Int_3_Loc: %x\n\n", Int_3_Loc); |
#endif |
|
Proc_1 (Ptr_Glob); |
#if DBG |
printf("c) Int_1_Loc: %x\n", Int_1_Loc); |
printf("c) Int_2_Loc: %x\n", Int_2_Loc); |
printf("c) Int_3_Loc: %x\n\n", Int_3_Loc); |
#endif |
|
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) |
/* loop body executed twice */ |
{ |
if (Enum_Loc == Func_1 (Ch_Index, 'C')) |
/* then, not executed */ |
{ |
Proc_6 (Ident_1, &Enum_Loc); |
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); |
Int_2_Loc = Run_Index; |
Int_Glob = Run_Index; |
#if DBG |
printf("d) Int_1_Loc: %x\n", Int_1_Loc); |
printf("d) Int_2_Loc: %x\n", Int_2_Loc); |
printf("d) Int_3_Loc: %x\n\n", Int_3_Loc); |
#endif |
} |
} |
|
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ |
#if DBG |
printf("e) Int_1_Loc: %x\n", Int_1_Loc); |
printf("e) Int_2_Loc: %x\n", Int_2_Loc); |
printf("e) Int_3_Loc: %x\n", Int_3_Loc); |
printf("e) Ch_1_Glob: %c\n\n", Ch_1_Glob); |
#endif |
Int_2_Loc = Int_2_Loc * Int_1_Loc; |
Int_1_Loc = Int_2_Loc * Int_3_Loc; |
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; |
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ |
Proc_2 (&Int_1_Loc); |
|
/* Int_1_Loc == 5 */ |
#if DBG |
printf("f) Int_1_Loc: %x\n", Int_1_Loc); |
printf("f) Int_2_Loc: %x\n", Int_2_Loc); |
printf("f) Int_3_Loc: %x\n\n", Int_3_Loc); |
#endif |
|
} /* loop "for Run_Index" */ |
|
/**************/ |
/* Stop timer */ |
/**************/ |
|
End_Time = read_timer(); |
|
/* printf ("Execution ends\n"); |
printf ("\n"); |
printf ("Final values of the variables used in the benchmark:\n"); |
printf ("\n"); |
printf ("Int_Glob: %d\n", Int_Glob); |
printf (" should be: %d\n", 5); |
printf ("Bool_Glob: %d\n", Bool_Glob); |
printf (" should be: %d\n", 1); |
printf ("Ch_1_Glob: %c\n", Ch_1_Glob); |
printf (" should be: %c\n", 'A'); |
printf ("Ch_2_Glob: %c\n", Ch_2_Glob); |
printf (" should be: %c\n", 'B'); |
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); |
printf (" should be: %d\n", 7); |
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); |
printf (" should be: Number_Of_Runs + 10\n"); |
printf ("Ptr_Glob->\n"); |
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp); |
printf (" should be: (implementation-dependent)\n"); |
printf (" Discr: %d\n", Ptr_Glob->Discr); |
printf (" should be: %d\n", 0); |
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp); |
printf (" should be: %d\n", 2); |
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp); |
printf (" should be: %d\n", 17); |
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp); |
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); |
printf ("Next_Ptr_Glob->\n"); |
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp); |
printf (" should be: (implementation-dependent), same as above\n"); |
printf (" Discr: %d\n", Next_Ptr_Glob->Discr); |
printf (" should be: %d\n", 0); |
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp); |
printf (" should be: %d\n", 1); |
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp); |
printf (" should be: %d\n", 18); |
printf (" Str_Comp: %s\n", |
Next_Ptr_Glob->variant.var_1.Str_Comp); |
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); |
printf ("Int_1_Loc: %d\n", Int_1_Loc); |
printf (" should be: %d\n", 5); |
printf ("Int_2_Loc: %d\n", Int_2_Loc); |
printf (" should be: %d\n", 13); |
printf ("Int_3_Loc: %d\n", Int_3_Loc); |
printf (" should be: %d\n", 7); |
printf ("Enum_Loc: %d\n", Enum_Loc); |
printf (" should be: %d\n", 1); |
printf ("Str_1_Loc: %s\n", Str_1_Loc); |
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); |
printf ("Str_2_Loc: %s\n", Str_2_Loc); |
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); |
|
*/ |
|
|
User_Time = End_Time - Begin_Time; |
/* microseconds */ |
|
printf("Begin Time = %d\n",Begin_Time); |
printf("End Time = %d\n",End_Time); |
|
printf ("\nNumber of Runs %i", num_runs); |
printf ("\nBegin Time %i", Begin_Time); |
printf ("\nEnd Time %i\n", End_Time); |
|
if (User_Time < Too_Small_Time) |
{ |
printf ("Measured time too small to obtain meaningful results\n"); |
printf ("Please increase number of runs\n"); |
printf ("\n"); |
} |
else |
{ |
#if DLX || OR1K |
// User_Time /= DLX_FREQ; |
#if DLX |
printf("DLX "); |
#else |
#if OR1K |
printf("OR1K "); |
#else |
printf("Unknown CPU "); |
#endif |
#endif |
printf("at %u MHz ", DLX_FREQ); |
if (PROC_6) |
printf("(+PROC_6)"); |
printf("\n"); |
#endif |
// Microseconds = User_Time / Number_Of_Runs; |
// Dhrystones_Per_Second = Number_Of_Runs * 1000 / User_Time; |
printf ("Microseconds for one run through Dhrystone: "); |
printf ("%d us / %d runs\n", User_Time,Number_Of_Runs); |
printf ("Dhrystones per Second: "); |
printf ("%d \n", Dhrystones_Per_Second); |
} |
return 0; |
#endif |
} |
|
|
void Proc_1(Ptr_Val_Par) |
/******************/ |
|
REG Rec_Pointer Ptr_Val_Par; |
/* executed once */ |
{ |
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp; |
/* == Ptr_Glob_Next */ |
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */ |
/* corresponds to "rename" in Ada, "with" in Pascal */ |
|
|
structassign(*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); |
Ptr_Val_Par->variant.var_1.Int_Comp = 5; |
Next_Record->variant.var_1.Int_Comp |
= Ptr_Val_Par->variant.var_1.Int_Comp; |
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp; |
Proc_3(&Next_Record->Ptr_Comp); |
/* |
* Ptr_Val_Par->Ptr_Comp->Ptr_Comp == Ptr_Glob->Ptr_Comp |
*/ |
if (Next_Record->Discr == Ident_1) |
/* then, executed */ |
{ |
Next_Record->variant.var_1.Int_Comp = 6; |
Proc_6(Ptr_Val_Par->variant.var_1.Enum_Comp, |
&Next_Record->variant.var_1.Enum_Comp); |
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp; |
Proc_7(Next_Record->variant.var_1.Int_Comp, 10, |
&Next_Record->variant.var_1.Int_Comp); |
} else /* not executed */ |
structassign(*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); |
|
} /* Proc_1 */ |
|
|
void |
Proc_2(Int_Par_Ref) |
/******************/ |
/* executed once */ |
/* *Int_Par_Ref == 1, becomes 4 */ |
|
One_Fifty *Int_Par_Ref; |
{ |
One_Fifty Int_Loc; |
Enumeration Enum_Loc = 0; |
|
|
Int_Loc = *Int_Par_Ref + 10; |
do /* executed once */ |
if (Ch_1_Glob == 'A') |
/* then, executed */ |
{ |
Int_Loc -= 1; |
*Int_Par_Ref = Int_Loc - Int_Glob; |
Enum_Loc = Ident_1; |
} /* if */ |
while (Enum_Loc != Ident_1);/* true */ |
} /* Proc_2 */ |
|
|
void |
Proc_3(Ptr_Ref_Par) |
/******************/ |
/* executed once */ |
/* Ptr_Ref_Par becomes Ptr_Glob */ |
|
Rec_Pointer *Ptr_Ref_Par; |
|
{ |
|
if (Ptr_Glob != Null) |
/* then, executed */ |
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp; |
Proc_7(10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp); |
} /* Proc_3 */ |
|
|
void |
Proc_4() |
{ /* without parameters */ |
/*******/ |
/* executed once */ |
Boolean Bool_Loc; |
|
|
Bool_Loc = Ch_1_Glob == 'A'; |
Bool_Glob = Bool_Loc | Bool_Glob; |
Ch_2_Glob = 'B'; |
} /* Proc_4 */ |
|
|
void |
Proc_5() |
{ /* without parameters */ |
/*******/ |
/* executed once */ |
|
Ch_1_Glob = 'A'; |
Bool_Glob = false; |
} /* Proc_5 */ |
|
/* @(#)dhry_2.c 1.2 92/05/28 14:44:54, AMD */ |
/* |
**************************************************************************** |
* |
* "DHRYSTONE" Benchmark Program |
* ----------------------------- |
* |
* Version: C, Version 2.1 |
* |
* File: dhry_2.c (part 3 of 3) |
* |
* Date: May 25, 1988 |
* |
* Author: Reinhold P. Weicker |
* |
**************************************************************************** |
*/ |
|
#ifndef REG |
#define REG |
/* REG becomes defined as empty */ |
/* i.e. no register variables */ |
#ifdef _AM29K |
#undef REG |
#define REG register /* Define REG; saves room on 127-char MS-DOS cmd line */ |
#endif |
#endif |
|
|
void |
Proc_6(Enum_Val_Par, Enum_Ref_Par) |
/*********************************/ |
/* executed once */ |
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */ |
|
Enumeration Enum_Val_Par; |
Enumeration *Enum_Ref_Par; |
{ |
#if PROC_6 |
|
*Enum_Ref_Par = Enum_Val_Par; |
if (!Func_3(Enum_Val_Par)) |
/* then, not executed */ |
*Enum_Ref_Par = Ident_4; |
switch (Enum_Val_Par) { |
case Ident_1: |
*Enum_Ref_Par = Ident_1; |
break; |
case Ident_2: |
if (Int_Glob > 100) |
/* then */ |
*Enum_Ref_Par = Ident_1; |
else |
*Enum_Ref_Par = Ident_4; |
break; |
case Ident_3: /* executed */ |
*Enum_Ref_Par = Ident_2; |
break; |
case Ident_4: |
break; |
case Ident_5: |
*Enum_Ref_Par = Ident_3; |
break; |
} /* switch */ |
#endif |
return; |
} /* Proc_6 */ |
|
void |
Proc_7(Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref) |
/**********************************************/ |
/* executed three times */ |
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ |
/* Int_Par_Ref becomes 7 */ |
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ |
/* Int_Par_Ref becomes 17 */ |
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */ |
/* Int_Par_Ref becomes 18 */ |
One_Fifty Int_1_Par_Val; |
One_Fifty Int_2_Par_Val; |
One_Fifty *Int_Par_Ref; |
{ |
One_Fifty Int_Loc; |
|
|
Int_Loc = Int_1_Par_Val + 2; |
*Int_Par_Ref = Int_2_Par_Val + Int_Loc; |
} /* Proc_7 */ |
|
|
void |
Proc_8(Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val) |
/*********************************************************************/ |
/* executed once */ |
/* Int_Par_Val_1 == 3 */ |
/* Int_Par_Val_2 == 7 */ |
Arr_1_Dim Arr_1_Par_Ref; |
Arr_2_Dim Arr_2_Par_Ref; |
int Int_1_Par_Val; |
int Int_2_Par_Val; |
{ |
REG One_Fifty Int_Index; |
REG One_Fifty Int_Loc; |
|
#if DBG |
printf("X) Int_1_Par_Val: %x\n", Int_1_Par_Val); |
printf("X) Int_2_Par_Val: %x\n", Int_2_Par_Val); |
#endif |
|
|
Int_Loc = Int_1_Par_Val + 5; |
Arr_1_Par_Ref[Int_Loc] = Int_2_Par_Val; |
Arr_1_Par_Ref[Int_Loc + 1] = Arr_1_Par_Ref[Int_Loc]; |
Arr_1_Par_Ref[Int_Loc + 30] = Int_Loc; |
for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index) |
Arr_2_Par_Ref[Int_Loc][Int_Index] = Int_Loc; |
Arr_2_Par_Ref[Int_Loc][Int_Loc - 1] += 1; |
Arr_2_Par_Ref[Int_Loc + 20][Int_Loc] = Arr_1_Par_Ref[Int_Loc]; |
Int_Glob = 5; |
|
#if DBG |
printf("Y) Int_1_Par_Val: %x\n", Int_1_Par_Val); |
printf("Y) Int_2_Par_Val: %x\n", Int_2_Par_Val); |
#endif |
|
} /* Proc_8 */ |
|
|
Enumeration |
Func_1(Ch_1_Par_Val, Ch_2_Par_Val) |
/*************************************************/ |
/* executed three times */ |
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */ |
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */ |
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */ |
|
Capital_Letter Ch_1_Par_Val; |
Capital_Letter Ch_2_Par_Val; |
{ |
Capital_Letter Ch_1_Loc; |
Capital_Letter Ch_2_Loc; |
|
|
Ch_1_Loc = Ch_1_Par_Val; |
Ch_2_Loc = Ch_1_Loc; |
if (Ch_2_Loc != Ch_2_Par_Val) |
/* then, executed */ |
return (Ident_1); |
else { /* not executed */ |
Ch_1_Glob = Ch_1_Loc; |
return (Ident_2); |
} |
} /* Func_1 */ |
|
|
Boolean |
Func_2(Str_1_Par_Ref, Str_2_Par_Ref) |
/*************************************************/ |
/* executed once */ |
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */ |
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */ |
|
Str_30 Str_1_Par_Ref; |
Str_30 Str_2_Par_Ref; |
{ |
REG One_Thirty Int_Loc; |
Capital_Letter Ch_Loc = 0; |
|
|
Int_Loc = 2; |
while (Int_Loc <= 2) /* loop body executed once */ |
if (Func_1(Str_1_Par_Ref[Int_Loc], |
Str_2_Par_Ref[Int_Loc + 1]) == Ident_1) |
/* then, executed */ |
{ |
Ch_Loc = 'A'; |
Int_Loc += 1; |
} /* if, while */ |
|
if (Ch_Loc >= 'W' && Ch_Loc < 'Z') |
/* then, not executed */ |
Int_Loc = 7; |
if (Ch_Loc == 'R') |
/* then, not executed */ |
return (true); |
else { /* executed */ |
if (strcmp(Str_1_Par_Ref, Str_2_Par_Ref) > 0) |
/* then, not executed */ |
{ |
Int_Loc += 7; |
Int_Glob = Int_Loc; |
return (true); |
} else /* executed */ |
return (false); |
} /* if Ch_Loc */ |
} /* Func_2 */ |
|
|
Boolean |
Func_3(Enum_Par_Val) |
/***************************/ |
/* executed once */ |
/* Enum_Par_Val == Ident_3 */ |
Enumeration Enum_Par_Val; |
{ |
Enumeration Enum_Loc; |
|
Enum_Loc = Enum_Par_Val; |
if (Enum_Loc == Ident_3) |
/* then, executed */ |
return (true); |
else /* not executed */ |
return (false); |
} /* Func_3 */ |
|
int dhry_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) dhry_main(strtoul (argv[0])); |
else if (argc == 0) dhry_main(20); |
else return -1; |
return 0; |
} |
|
void module_dhry_init (void) |
{ |
register_command ("dhry", "[<num_runs>]", "run dhrystone", dhry_cmd); |
} |
/cmds/cpu.c
0,0 → 1,113
#include "common.h" |
#include "spr_defs.h" |
|
int ic_enable_cmd (int argc, char *argv[]) |
{ |
unsigned long addr; |
unsigned long sr; |
|
if (argc) return -1; |
/* Invalidate IC */ |
for (addr = 0; addr < 8192; addr += 16) |
asm("l.mtspr r0,%0,%1": : "r" (addr), "i" (SPR_ICBIR)); |
|
/* Enable IC */ |
asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR)); |
sr |= SPR_SR_ICE; |
asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR)); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
return 0; |
} |
|
int ic_disable_cmd (int argc, char *argv[]) |
{ |
unsigned long sr; |
|
if (argc) return -1; |
/* Disable IC */ |
asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR)); |
sr &= ~SPR_SR_ICE; |
asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR)); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
return 0; |
} |
|
int dc_enable_cmd (int argc, char *argv[]) |
{ |
unsigned long addr; |
unsigned long sr; |
|
if (argc) return -1; |
/* Invalidate DC */ |
for (addr = 0; addr < 8192; addr += 16) |
asm("l.mtspr r0,%0,%1": : "r" (addr), "i" (SPR_DCBIR)); |
|
/* Enable DC */ |
asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR)); |
sr |= SPR_SR_DCE; |
asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR)); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
return 0; |
} |
|
int dc_disable_cmd (int argc, char *argv[]) |
{ |
unsigned long sr; |
|
if (argc) return -1; |
/* Disable DC */ |
asm("l.mfspr %0,r0,%1": "=r" (sr) : "i" (SPR_SR)); |
sr &= ~SPR_SR_DCE; |
asm("l.mtspr r0,%0,%1": : "r" (sr), "i" (SPR_SR)); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
asm("l.nop"); |
return 0; |
} |
|
int mfspr_cmd (int argc, char *argv[]) |
{ |
unsigned long val, addr; |
|
if (argc == 1) { |
addr = strtoul (argv[0]); |
/* Read SPR */ |
asm("l.mfspr %0,%1,0": "=r" (val) : "r" (addr)); |
printf ("\nSPR %04lx: %08lx", addr, val); |
} else return -1; |
return 0; |
} |
|
int mtspr_cmd (int argc, char *argv[]) |
{ |
unsigned long val, addr; |
if (argc == 2) { |
addr = strtoul (argv[0]); |
val = strtoul (argv[1]); |
/* Write SPR */ |
asm("l.mtspr %0,%1,0": : "r" (addr), "r" (val)); |
asm("l.mfspr %0,%1,0": "=r" (val) : "r" (addr)); |
printf ("\nSPR %04lx: %08lx", addr, val); |
} else return -1; |
return 0; |
} |
|
void module_cpu_init (void) |
{ |
register_command ("ic_enable", "", "enable instruction cache", ic_enable_cmd); |
register_command ("ic_disable", "", "disable instruction cache", ic_disable_cmd); |
register_command ("dc_enable", "", "enable data cache", dc_enable_cmd); |
register_command ("dc_disable", "", "disable data cache", dc_disable_cmd); |
register_command ("mfspr", "<spr_addr>", "show SPR", mfspr_cmd); |
register_command ("mtspr", "<spr_addr> <value>", "set SPR", mtspr_cmd); |
} |
/cmds/camera.c
0,0 → 1,146
#include "common.h" |
#include "support.h" |
#include "spr_defs.h" |
|
/* Camera and CRT test. |
Draws gray cross across the screen, few color boxes at top left and moves around camera captured screen left/right |
in the middle. */ |
|
#define CAMERA_BASE 0x88000000 |
#define CRT_BASE 0xc0000000 |
#define VIDEO_RAM_START 0xa8000000 /* till including a83ffffc */ |
|
#define SCREEN_X 640 |
#define SCREEN_Y 480 |
|
#define CAMERA_X 352 |
#define CAMERA_Y 288 |
|
#define CAMERA_BUF(idx) (VIDEO_RAM_START + (idx) * CAMERA_X * CAMERA_Y) |
#define FRAME_BUF (CAMERA_BUF(2)) |
|
#define CAMERA_POS (camera_pos_x + ((SCREEN_Y - CAMERA_Y) / 2) * SCREEN_X) |
|
#define MIN(x,y) ((x) < (y) ? (x) : (y)) |
|
#define set_mem32(addr,val) (*((unsigned long *) (addr)) = (val)) |
#define get_mem32(addr) (*((unsigned long *) (addr))) |
#define set_palette(idx,r,g,b) set_mem32 (CRT_BASE + 0x400 + (idx) * 4, (((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0)) |
#define put_pixel(xx,yy,idx) (*(unsigned char *)(FRAME_BUF + (xx) + (yy) * SCREEN_X) = (idx)) |
|
int camera_pos_x; |
int camera_move_speed = 1; |
int current_buf; |
|
void int_main (void) |
{ |
/* Change base addresse of camera */ |
set_mem32 (CAMERA_BASE, CAMERA_BUF(current_buf)); /* Set address to store to */ |
|
/* Change base addresse of crt */ |
set_mem32 (CRT_BASE + 8, CAMERA_BUF(1 - current_buf)); /* Tell CRT when camera buffer is */ |
printf ("\n %08x\n ", CAMERA_BUF(current_buf)); |
|
current_buf = 1 - current_buf; |
|
/* move the camera screen around */ |
camera_pos_x += camera_move_speed; |
if (camera_pos_x >= SCREEN_X - CAMERA_X || camera_pos_x <= 0) |
camera_move_speed = -camera_move_speed; |
mtspr(SPR_PICSR, 0); |
} |
|
int crt_enable_cmd (int argc, char *argv[]) |
{ |
int i, x, y; |
|
if (argc) return -1; |
/* Init CRT */ |
set_mem32 (CRT_BASE + 4, FRAME_BUF); /* Frame buffer start */ |
set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) | 1); /* Enable CRT only */ |
|
/* Init palette */ |
for (i = 0; i < 32; i++) { |
set_palette (8 * i + 0, 0x00, 0x00, 0x00); /* black */ |
set_palette (8 * i + 1, 0xff, 0xff, 0xff); /* white */ |
set_palette (8 * i + 2, 0x7f, 0x7f, 0x7f); /* gray */ |
set_palette (8 * i + 3, 0xff, 0x00, 0x00); /* red */ |
set_palette (8 * i + 4, 0x00, 0xff, 0x00); /* green */ |
set_palette (8 * i + 5, 0x00, 0x00, 0xff); /* blue */ |
set_palette (8 * i + 6, 0x00, 0xff, 0xff); /* cyan */ |
set_palette (8 * i + 7, 0xff, 0x00, 0xff); /* purple */ |
} |
for (x = 0; x < SCREEN_X; x++) |
for (y = 0; y < SCREEN_Y; y++) |
put_pixel(x, y, 3); |
return 0; |
} |
|
int crt_test_cmd (int argc, char *argv[]) |
{ |
int i, x, y; |
if (argc) return -1; |
for (x = 0; x < SCREEN_X; x++) |
for (y = 0; y < SCREEN_Y; y++) |
put_pixel(x, y, 0); |
/* Draw gray X */ |
for (i = 0; i < SCREEN_Y; i++) { |
put_pixel (i, i, 2); |
put_pixel (SCREEN_X - i - 1, i, 1); |
} |
|
/* Draw color boxes */ |
for (y = 0; y < 50; y++) |
for (x = 0; x < 50; x++) |
for (i = 0; i < 8; i++) |
put_pixel (i * 50 + x, y, i); |
return 0; |
} |
|
int crt_disable_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) & ~1); /* Disable CRT */ |
return 0; |
} |
|
int camera_enable_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
/* Init Camera */ |
set_mem32 (CAMERA_BASE, CAMERA_BUF(current_buf = 0)); /* Set address to store to */ |
set_mem32 (CAMERA_BASE + 4, 1); /* Enable it */ |
|
/* Init CRT to display camera */ |
set_mem32 (CRT_BASE + 8, CAMERA_BUF(1 - current_buf)); /* Tell CRT when camera buffer is */ |
camera_pos_x = 0; |
set_mem32 (CRT_BASE + 0xc, CAMERA_POS); |
set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) | 2); /* Enable camera overlay */ |
|
/* Enable interrupts */ |
mtspr (SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE); |
mtspr (SPR_PICMR, mfspr(SPR_PICSR) | (1 << 13)); |
return 0; |
} |
|
int camera_disable_cmd (int argc, char *argv[]) |
{ |
if (argc) return -1; |
/* Disable interrupts */ |
mtspr (SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE); |
mtspr (SPR_PICMR, mfspr(SPR_PICSR) & ~(1 << 13)); |
|
/* Disable Camera */ |
set_mem32 (CAMERA_BASE + 4, 1); /* Enable it */ |
set_mem32 (CRT_BASE, get_mem32 (CRT_BASE) & ~2); /* Disable camera overlay */ |
return 0; |
} |
|
void module_camera_init (void) |
{ |
register_command ("crt_enable", "", "enables CRT", crt_enable_cmd); |
register_command ("crt_disable", "", "disables CRT", crt_disable_cmd); |
register_command ("crt_test", "", "enables CRT and displays some test patterns", crt_test_cmd); |
register_command ("camera_enable", "", "enables camera", camera_enable_cmd); |
register_command ("camera_disable", "", "disables camera", camera_disable_cmd); |
} |
/cmds/memory.c
0,0 → 1,159
#include "common.h" |
#include "support.h" |
#include "spr_defs.h" |
|
#define printf(...) |
//#define strtoul(x) 0 |
#define register_command(...) |
|
void show_mem(int start, int stop) |
{ |
unsigned long i; |
getc(); |
if (((i = start) & 0xf) != 0x0) |
printf ("\n%08lx: ", i); |
for(; i<=stop; i += 4){ |
if ((i & 0xf) == 0x0) |
printf ("\n%08lx: ", i); |
|
/* Read one word */ |
printf ("%08lx ", REG32(i)); |
} |
printf ("\n"); |
} |
|
void testram (unsigned long start_addr, unsigned long stop_addr, unsigned long testno) |
{ |
unsigned long addr; |
unsigned long err_addr = 0; |
unsigned long err_no = 0; |
|
/* Test 1: Write locations with their addresses */ |
if ((testno == 1) || (testno == 0)) |
{ |
printf ("\n1. Writing locations with their addresses: "); |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
REG32(addr) = addr; |
|
/* Verify */ |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
if (REG32(addr) != addr) |
{ |
err_no++; |
err_addr = addr; |
} |
if (err_no) |
{ |
printf ("%04lx times failed. Last at location %08lx", err_no, err_addr); |
} else |
printf ("Passed"); |
err_no = 0; |
} |
|
/* Test 2: Write locations with their inverse address */ |
if ((testno == 2) || (testno == 0)) |
{ |
printf ("\n2. Writing locations with their inverse addresses: "); |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
REG32(addr) = ~addr; |
|
/* Verify */ |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
if (REG32(addr) != ~addr) |
{ |
err_no++; |
err_addr = addr; |
} |
if (err_no) |
{ |
printf ("%04lx times failed. Last at location %08lx", err_no, err_addr); |
} else |
printf ("Passed"); |
err_no = 0; |
} |
|
/* Test 3: Write locations with walking ones */ |
if ((testno == 3) || (testno == 0)) |
{ |
printf ("\n3. Writing locations with walking ones: "); |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
REG32(addr) = 1 << (addr >> 2); |
|
/* Verify */ |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
if (REG32(addr) != (1 << (addr >> 2))) |
{ |
err_no++; |
err_addr = addr; |
} |
if (err_no) |
{ |
printf ("%04lx times failed. Last at location %08lx", err_no, err_addr); |
} else |
printf ("Passed"); |
err_no = 0; |
} |
|
/* Test 4: Write locations with walking zeros */ |
if ((testno == 4) || (testno == 0)) |
{ |
printf ("\n4. Writing locations with walking zeros: "); |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
REG32(addr) = ~(1 << (addr >> 2)); |
|
/* Verify */ |
for (addr = start_addr; addr <= stop_addr; addr += 4) |
if (REG32(addr) != ~(1 << (addr >> 2))) |
{ |
err_no++; |
err_addr = addr; |
} |
if (err_no) |
{ |
printf ("%04lx times failed. Last at location %08lx", err_no, err_addr); |
} else |
printf ("Passed"); |
err_no = 0; |
} |
} |
|
int dm_cmd (int argc, char *argv[]) |
{ |
if (argc == 1) show_mem (strtoul (argv[0]), strtoul (argv[0])); |
else if (argc == 2) show_mem (strtoul (argv[0]), strtoul (argv[1])); |
else return -1; |
return 0; |
} |
|
int pm_cmd (int argc, char *argv[]) |
{ |
if ((argc == 3) || (argc == 2)) { |
unsigned long addr = strtoul (argv[0]); |
unsigned long stop_addr = strtoul (argv[1]); |
unsigned long value = strtoul (argv[2]); |
|
if (argc == 2) { |
stop_addr = strtoul (argv[0]); |
value = strtoul (argv[1]); |
} |
|
for (; addr <= stop_addr; addr += 4) REG32(addr) = value; |
show_mem(strtoul (argv[0]), stop_addr); |
} else return -1; |
return 0; |
} |
|
int ram_test_cmd (int argc, char *argv[]) |
{ |
if (argc == 2) testram(strtoul (argv[0]), strtoul (argv[1]), 0); |
else if (argc == 3) testram(strtoul (argv[0]), strtoul (argv[1]), strtoul (argv[2])); |
else return -1; |
return 0; |
} |
|
void module_memory_init (void) |
{ |
register_command ("dm", "<start addr> [<end addr>]", "display memory location 32-bit", dm_cmd); |
register_command ("pm", "<addr> [<stop_addr>] <value>", "patch memory location 32-bit", pm_cmd); |
register_command ("ram_test", "<start_addr> <stop_addr> [<test_no>]", "run a simple RAM test\n", ram_test_cmd); |
} |
/cmds/dhry.h
0,0 → 1,412
/* |
**************************************************************************** |
* |
* "DHRYSTONE" Benchmark Program |
* ----------------------------- |
* |
* Version: C, Version 2.1 |
* |
* File: dhry.h (part 1 of 3) |
* |
* Date: May 25, 1988 |
* |
* Author: Reinhold P. Weicker |
* Siemens AG, AUT E 51 |
* Postfach 3220 |
* 8520 Erlangen |
* Germany (West) |
* Phone: [+49]-9131-7-20330 |
* (8-17 Central European Time) |
* Usenet: ..!mcsun!unido!estevax!weicker |
* |
* Original Version (in Ada) published in |
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), |
* pp. 1013 - 1030, together with the statistics |
* on which the distribution of statements etc. is based. |
* |
* In this C version, the following C library functions are used: |
* - strcpy, strcmp (inside the measurement loop) |
* - printf, scanf (outside the measurement loop) |
* In addition, Berkeley UNIX system calls "times ()" or "time ()" |
* are used for execution time measurement. For measurements |
* on other systems, these calls have to be changed. |
* |
* Updated January, 1997 Rick Cramer, Galileo(R) to work with |
* the i960jx and Galileo-5 Reference Design. |
* |
* |
* Collection of Results: |
* Reinhold Weicker (address see above) and |
* |
* Rick Richardson |
* PC Research. Inc. |
* 94 Apple Orchard Drive |
* Tinton Falls, NJ 07724 |
* Phone: (201) 389-8963 (9-17 EST) |
* Usenet: ...!uunet!pcrat!rick |
* |
* Please send results to Rick Richardson and/or Reinhold Weicker. |
* Complete information should be given on hardware and software used. |
* Hardware information includes: Machine type, CPU, type and size |
* of caches; for microprocessors: clock frequency, memory speed |
* (number of wait states). |
* Software information includes: Compiler (and runtime library) |
* manufacturer and version, compilation switches, OS version. |
* The Operating System version may give an indication about the |
* compiler; Dhrystone itself performs no OS calls in the measurement loop. |
* |
* The complete output generated by the program should be mailed |
* such that at least some checks for correctness can be made. |
* |
*************************************************************************** |
* |
* History: This version C/2.1 has been made for two reasons: |
* |
* 1) There is an obvious need for a common C version of |
* Dhrystone, since C is at present the most popular system |
* programming language for the class of processors |
* (microcomputers, minicomputers) where Dhrystone is used most. |
* There should be, as far as possible, only one C version of |
* Dhrystone such that results can be compared without |
* restrictions. In the past, the C versions distributed |
* by Rick Richardson (Version 1.1) and by Reinhold Weicker |
* had small (though not significant) differences. |
* |
* 2) As far as it is possible without changes to the Dhrystone |
* statistics, optimizing compilers should be prevented from |
* removing significant statements. |
* |
* This C version has been developed in cooperation with |
* Rick Richardson (Tinton Falls, NJ), it incorporates many |
* ideas from the "Version 1.1" distributed previously by |
* him over the UNIX network Usenet. |
* I also thank Chaim Benedelac (National Semiconductor), |
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS), |
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) |
* for their help with comments on earlier versions of the |
* benchmark. |
* |
* Changes: In the initialization part, this version follows mostly |
* Rick Richardson's version distributed via Usenet, not the |
* version distributed earlier via floppy disk by Reinhold Weicker. |
* As a concession to older compilers, names have been made |
* unique within the first 8 characters. |
* Inside the measurement loop, this version follows the |
* version previously distributed by Reinhold Weicker. |
* |
* At several places in the benchmark, code has been added, |
* but within the measurement loop only in branches that |
* are not executed. The intention is that optimizing compilers |
* should be prevented from moving code out of the measurement |
* loop, or from removing code altogether. Since the statements |
* that are executed within the measurement loop have NOT been |
* changed, the numbers defining the "Dhrystone distribution" |
* (distribution of statements, operand types and locality) |
* still hold. Except for sophisticated optimizing compilers, |
* execution times for this version should be the same as |
* for previous versions. |
* |
* Since it has proven difficult to subtract the time for the |
* measurement loop overhead in a correct way, the loop check |
* has been made a part of the benchmark. This does have |
* an impact - though a very minor one - on the distribution |
* statistics which have been updated for this version. |
* |
* All changes within the measurement loop are described |
* and discussed in the companion paper "Rationale for |
* Dhrystone version 2". |
* |
* Because of the self-imposed limitation that the order and |
* distribution of the executed statements should not be |
* changed, there are still cases where optimizing compilers |
* may not generate code for some statements. To a certain |
* degree, this is unavoidable for small synthetic benchmarks. |
* Users of the benchmark are advised to check code listings |
* whether code is generated for all statements of Dhrystone. |
* |
* Version 2.1 is identical to version 2.0 distributed via |
* the UNIX network Usenet in March 1988 except that it corrects |
* some minor deficiencies that were found by users of version 2.0. |
* The only change within the measurement loop is that a |
* non-executed "else" part was added to the "if" statement in |
* Func_3, and a non-executed "else" part removed from Proc_3. |
* |
*************************************************************************** |
* |
* Defines: The following "Defines" are possible: |
* -DREG=register (default: Not defined) |
* As an approximation to what an average C programmer |
* might do, the "register" storage class is applied |
* (if enabled by -DREG=register) |
* - for local variables, if they are used (dynamically) |
* five or more times |
* - for parameters if they are used (dynamically) |
* six or more times |
* Note that an optimal "register" strategy is |
* compiler-dependent, and that "register" declarations |
* do not necessarily lead to faster execution. |
* -DNOSTRUCTASSIGN (default: Not defined) |
* Define if the C compiler does not support |
* assignment of structures. |
* -DNOENUMS (default: Not defined) |
* Define if the C compiler does not support |
* enumeration types. |
* -DICACHEON (default: Not defined) |
* Adjust performace by conditionally compiling |
* these i960jx CACHE paramaters. |
* -DICACHEOFF |
* -DDCACHEON (default: Not defined) |
* -DDCACHEOFF |
* |
* NOTE: Galileo-5 Board Frequency is set to 33Mhz in the |
* file jx-timer.c. If the operating frequency is |
* changed by replacing the crystal, then this #define |
* must also be changed. |
* |
*************************************************************************** |
* |
* Compilation model and measurement (IMPORTANT): |
* |
* This C version of Dhrystone consists of four files: |
* - dhry.h (this file, containing global definitions and comments) |
* - dhry_1.c (containing the code corresponding to Ada package Pack_1) |
* - dhry_2.c (containing the code corresponding to Ada package Pack_2) |
* - jx-timer.c (containing the code to access the i960jx timer) |
* |
* The following "ground rules" apply for measurements: |
* - No procedure merging |
* - Otherwise, compiler optimizations are allowed but should be indicated |
* - Default results are those without register declarations |
* See the companion paper "Rationale for Dhrystone Version 2" for a more |
* detailed discussion of these ground rules. |
* |
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation |
* models ("small", "medium", "large" etc.) should be given if possible, |
* together with a definition of these models for the compiler system used. |
* |
* Example Intel 960jx compile syntax for Galileo-5. |
* |
* ic960 -AJA -Tgal5 -O2 -DREG=register dhry_1.c dhry_2.c jx-timer.c |
* |
************************************************************************** |
* |
* Dhrystone (C version) statistics: |
* |
* [Comment from the first distribution, updated for version 2. |
* Note that because of language differences, the numbers are slightly |
* different from the Ada version.] |
* |
* The following program contains statements of a high level programming |
* language (here: C) in a distribution considered representative: |
* |
* assignments 52 (51.0 %) |
* control statements 33 (32.4 %) |
* procedure, function calls 17 (16.7 %) |
* |
* 103 statements are dynamically executed. The program is balanced with |
* respect to the three aspects: |
* |
* - statement type |
* - operand type |
* - operand locality |
* operand global, local, parameter, or constant. |
* |
* The combination of these three aspects is balanced only approximately. |
* |
* 1. Statement Type: |
* ----------------- number |
* |
* V1 = V2 9 |
* (incl. V1 = F(..) |
* V = Constant 12 |
* Assignment, 7 |
* with array element |
* Assignment, 6 |
* with record component |
* -- |
* 34 34 |
* |
* X = Y +|-|"&&"|"|" Z 5 |
* X = Y +|-|"==" Constant 6 |
* X = X +|- 1 3 |
* X = Y *|/ Z 2 |
* X = Expression, 1 |
* two operators |
* X = Expression, 1 |
* three operators |
* -- |
* 18 18 |
* |
* if .... 14 |
* with "else" 7 |
* without "else" 7 |
* executed 3 |
* not executed 4 |
* for ... 7 | counted every time |
* while ... 4 | the loop condition |
* do ... while 1 | is evaluated |
* switch ... 1 |
* break 1 |
* declaration with 1 |
* initialization |
* -- |
* 34 34 |
* |
* P (...) procedure call 11 |
* user procedure 10 |
* library procedure 1 |
* X = F (...) |
* function call 6 |
* user function 5 |
* library function 1 |
* -- |
* 17 17 |
* --- |
* 103 |
* |
* The average number of parameters in procedure or function calls |
* is 1.82 (not counting the function values as implicit parameters). |
* |
* |
* 2. Operators |
* ------------ |
* number approximate |
* percentage |
* |
* Arithmetic 32 50.8 |
* |
* + 21 33.3 |
* - 7 11.1 |
* * 3 4.8 |
* / (int div) 1 1.6 |
* |
* Comparison 27 42.8 |
* |
* == 9 14.3 |
* /= 4 6.3 |
* > 1 1.6 |
* < 3 4.8 |
* >= 1 1.6 |
* <= 9 14.3 |
* |
* Logic 4 6.3 |
* |
* && (AND-THEN) 1 1.6 |
* | (OR) 1 1.6 |
* ! (NOT) 2 3.2 |
* |
* -- ----- |
* 63 100.1 |
* |
* |
* 3. Operand Type (counted once per operand reference): |
* --------------- |
* number approximate |
* percentage |
* |
* Integer 175 72.3 % |
* Character 45 18.6 % |
* Pointer 12 5.0 % |
* String30 6 2.5 % |
* Array 2 0.8 % |
* Record 2 0.8 % |
* --- ------- |
* 242 100.0 % |
* |
* When there is an access path leading to the final operand (e.g. a record |
* component), only the final data type on the access path is counted. |
* |
* |
* 4. Operand Locality: |
* ------------------- |
* number approximate |
* percentage |
* |
* local variable 114 47.1 % |
* global variable 22 9.1 % |
* parameter 45 18.6 % |
* value 23 9.5 % |
* reference 22 9.1 % |
* function result 6 2.5 % |
* constant 55 22.7 % |
* --- ------- |
* 242 100.0 % |
* |
* |
* The program does not compute anything meaningful, but it is syntactically |
* and semantically correct. All variables have a value assigned to them |
* before they are used as a source operand. |
* |
* There has been no explicit effort to account for the effects of a |
* cache, or to balance the use of long or short displacements for code or |
* data. |
* |
*************************************************************************** |
*/ |
|
/* Compiler and system dependent definitions: */ |
|
|
#define Mic_secs_Per_Second 1000000.0 |
/* Berkeley UNIX C returns process times in seconds/HZ */ |
|
#ifdef NOSTRUCTASSIGN |
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) |
#else |
#define structassign(d, s) d = s |
#endif |
|
#define NOENUM |
#ifdef NOENUM |
#define Ident_1 0 |
#define Ident_2 1 |
#define Ident_3 2 |
#define Ident_4 3 |
#define Ident_5 4 |
typedef int Enumeration; |
#else |
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} |
Enumeration; |
#endif |
/* for boolean and enumeration types in Ada, Pascal */ |
|
/* General definitions: */ |
|
/* #include <stdio.h> */ |
/* for strcpy, strcmp */ |
|
#define Null 0 |
/* Value of a Null pointer */ |
#define true 1 |
#define false 0 |
|
typedef int One_Thirty; |
typedef int One_Fifty; |
typedef char Capital_Letter; |
typedef int Boolean; |
typedef char Str_30 [31]; |
typedef int Arr_1_Dim [50]; |
typedef int Arr_2_Dim [50] [50]; |
|
typedef struct record |
{ |
struct record *Ptr_Comp; |
Enumeration Discr; |
union { |
struct { |
Enumeration Enum_Comp; |
int Int_Comp; |
char Str_Comp [31]; |
} var_1; |
struct { |
Enumeration E_Comp_2; |
char Str_2_Comp [31]; |
} var_2; |
struct { |
char Ch_1_Comp; |
char Ch_2_Comp; |
} var_3; |
} variant; |
} Rec_Type, *Rec_Pointer; |
|
|
/cmds/Makefile
0,0 → 1,13
|
LIB = cmds.o |
#OBJS = dhry.o eth.o cpu.o camera.o tftp.o memory.o |
OBJS = eth.o cpu.o camera.o tftp.o memory.o global.o |
|
all: $(LIB) |
|
$(LIB): $(OBJS) |
$(LD) -r -o $@ $(OBJS) |
|
.depend: Makefile $(OBJS:.o=.c) |
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ |
sinclude .depend |
/cmds/tftp.c
0,0 → 1,15
#include "common.h" |
#include "net.h" |
|
unsigned long load_addr; |
|
int tftp_cmd (int argc, char *argv[]) |
{ |
NetLoop(TFTP); |
return 0; |
} |
|
void module_tftp_init (void) |
{ |
register_command ("tftp", "[<file>] [<ip>]", "TFTP download", tftp_cmd); |
} |
/common/screen.c
0,0 → 1,90
#include "common.h" |
#include "screen.h" |
|
#if CRT_ENABLED |
unsigned long fg_color = COLOR_WHITE; |
unsigned long bg_color = COLOR_BLACK; |
int cx = 0; |
int cy = 0; |
|
extern unsigned char font[256][12]; |
static char screen[CHARSY][CHARSX]; |
|
void put_char_xy (int x, int y, char c) { |
int i, j; |
screen[y][x] = c; |
x *= CHAR_WIDTH; |
y *= CHAR_HEIGHT; |
for (i = 0; i < CHAR_HEIGHT; i++) { |
int t = font[(unsigned char)c][i]; |
for (j = 0; j < CHAR_WIDTH; j++) { |
if (t & 1) |
PUT_PIXEL(x + j, y + i, fg_color); |
else |
PUT_PIXEL(x + j, y + i, bg_color); |
t >>= 1; |
} |
} |
} |
|
static void scroll (void) { |
int x,y; |
for (y = 1; y < CHARSY; y++) |
for (x = 0; x < CHARSX; x++) |
put_char_xy (x, y-1, screen[y][x]); |
for (x = 0; x < CHARSX; x++) |
put_char_xy (x, CHARSY-1, ' '); |
cy--; |
} |
|
void screen_putc (char c) { |
int t; |
switch (c) { |
case '\n': |
cy++; |
cx = 0; |
if (cy >= CHARSY) |
scroll(); |
break; |
case '\r': |
cx = 0; |
break; |
case '\t': |
for (t = 0; t < 8 - (cx & 7); t++) |
screen_putc (' '); |
break; |
default: |
cx++; |
if(cx >= CHARSX) screen_putc ('\n'); |
put_char_xy(cx, cy, c); |
break; |
} |
} |
|
void screen_clear () { |
int x, y; |
for (y = 0; y < CHARSY; y++) |
for (x = 0; x < CHARSX; x++) |
put_char_xy (x, y, ' '); |
cx = cy = 0; |
} |
|
void screen_puts (char *s) { |
while (*s) { |
screen_putc (*s); |
s++; |
} |
} |
|
void screen_init () { |
SET_PALLETE(COLOR_BLACK, 0, 0, 0); |
SET_PALLETE(COLOR_WHITE, 255, 255, 255); |
|
/* Set screen offset */ |
*((unsigned long *)CRT_BUFFER_REG) = FB_BASE_ADD; |
|
/* Turn screen on */ |
*((unsigned long *)CRT_REG) = 0x00000001; |
} |
|
#endif /* CRT_ENABLED */ |
/common/int.h
0,0 → 1,15
|
/* Number of interrupt handlers */ |
#define MAX_INT_HANDLERS 32 |
|
/* Handler entry */ |
struct ihnd { |
void (*handler)(void *); |
void *arg; |
}; |
|
/* Add interrupt handler */ |
int int_add(unsigned long vect, void (* handler)(void *), void *arg); |
|
/* Initialize routine */ |
int int_init(void); |
/common/cprintf.c
0,0 → 1,857
/* |
FUNCTION |
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list |
|
INDEX |
vprintf |
INDEX |
vfprintf |
INDEX |
vsprintf |
INDEX |
vsnprintf |
|
ANSI_SYNOPSIS |
#include <stdio.h> |
#include <stdarg.h> |
int vprintf(const char *<[fmt]>, va_list <[list]>); |
int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>); |
int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>); |
int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, va_list <[list]>); |
|
int _vprintf_r(void *<[reent]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>, |
va_list <[list]>); |
int _vsnprintf_r(void *<[reent]>, char *<[str]>, size_t <[size]>, const char *<[fmt]>, |
va_list <[list]>); |
|
TRAD_SYNOPSIS |
#include <stdio.h> |
#include <varargs.h> |
int vprintf( <[fmt]>, <[list]>) |
char *<[fmt]>; |
va_list <[list]>; |
|
int vfprintf(<[fp]>, <[fmt]>, <[list]>) |
FILE *<[fp]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int vsprintf(<[str]>, <[fmt]>, <[list]>) |
char *<[str]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int vsnprintf(<[str]>, <[size]>, <[fmt]>, <[list]>) |
char *<[str]>; |
size_t <[size]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int _vprintf_r(<[reent]>, <[fmt]>, <[list]>) |
char *<[reent]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>) |
char *<[reent]>; |
FILE *<[fp]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>) |
char *<[reent]>; |
char *<[str]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
int _vsnprintf_r(<[reent]>, <[str]>, <[size]>, <[fmt]>, <[list]>) |
char *<[reent]>; |
char *<[str]>; |
size_t <[size]>; |
char *<[fmt]>; |
va_list <[list]>; |
|
DESCRIPTION |
<<vprintf>>, <<vfprintf>>, <<vsprintf>> and <<vsnprintf>> are (respectively) |
variants of <<printf>>, <<fprintf>>, <<sprintf>> and <<snprintf>>. They differ |
only in allowing their caller to pass the variable argument list as a |
<<va_list>> object (initialized by <<va_start>>) rather than directly |
accepting a variable number of arguments. |
|
RETURNS |
The return values are consistent with the corresponding functions: |
<<vsprintf>> returns the number of bytes in the output string, |
save that the concluding <<NULL>> is not counted. |
<<vprintf>> and <<vfprintf>> return the number of characters transmitted. |
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No |
error returns occur for <<vsprintf>>. |
|
PORTABILITY |
ANSI C requires all three functions. |
|
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
*/ |
|
/*- |
* Copyright (c) 1990 The Regents of the University of California. |
* All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Chris Torek. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
|
#define INTEGER_ONLY |
#define _HAVE_STDC_ |
#define u_long unsigned long |
#define u_short unsigned short |
#define u_int unsigned int |
#define _uquad_t u_long |
#define _POINTER_INT int |
#define _CONST const |
#define NULL 0 |
|
#include "common.h" |
#include "support.h" |
|
#if defined(LIBC_SCCS) && !defined(lint) |
/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/ |
static char *rcsid = "$Id: cprintf.c,v 1.1.1.1 2002-04-11 10:47:29 simons Exp $"; |
#endif /* LIBC_SCCS and not lint */ |
|
/* |
* Actual printf innards. |
* |
* This code is large and complicated... |
*/ |
|
#ifdef INTEGER_ONLY |
#define VFPRINTF vfiprintf |
#define _VFPRINTF_R _vfiprintf_r |
#else |
#define VFPRINTF vfprintf |
#define _VFPRINTF_R _vfprintf_r |
#define FLOATING_POINT |
#endif |
|
#define _NO_LONGLONG |
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__ |
# undef _NO_LONGLONG |
#endif |
|
#include <stdarg.h> |
|
#ifdef FLOATING_POINT |
#include <locale.h> |
#include <math.h> |
#include "floatio.h" |
|
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ |
#define DEFPREC 6 |
|
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *)); |
static int exponent _PARAMS((char *, int, int)); |
|
#else /* no FLOATING_POINT */ |
|
#define BUF 40 |
|
#endif /* FLOATING_POINT */ |
|
/* |
* Macros for converting digits to letters and vice versa |
*/ |
#define to_digit(c) ((c) - '0') |
#define is_digit(c) ((unsigned)to_digit(c) <= 9) |
#define to_char(n) ((n) + '0') |
|
/* |
* Flags used during conversion. |
*/ |
#define ALT 0x001 /* alternate form */ |
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ |
#define LADJUST 0x004 /* left adjustment */ |
#define LONGDBL 0x008 /* long double; unimplemented */ |
#define LONGINT 0x010 /* long integer */ |
#define QUADINT 0x020 /* quad integer */ |
#define SHORTINT 0x040 /* short integer */ |
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ |
#define FPT 0x100 /* Floating point number */ |
|
/* |
* Choose PADSIZE to trade efficiency vs. size. If larger printf |
* fields occur frequently, increase PADSIZE and make the initialisers |
* below longer. |
*/ |
#define PADSIZE 16 /* pad chunk size */ |
static _CONST char blanks[PADSIZE] = |
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; |
static _CONST char zeroes[PADSIZE] = |
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; |
|
inline void pc (_CONST char c) { |
#ifdef OR1K |
putc (c); |
#else |
printf ("%c", c); |
#endif |
} |
/* |
* BEWARE, these `goto error' on error, and PAD uses `n'. |
*/ |
inline void PRINT(_CONST char *ptr, int len) { |
int i; |
for (i = 0; i < len; i++) |
pc(*(ptr++)); |
} |
|
inline void PAD(int howmany, _CONST char *with) { |
int n; |
if ((n = howmany) > 0) { |
while (n > PADSIZE) { |
PRINT(with, PADSIZE); |
n -= PADSIZE; |
} |
PRINT(with, n); |
} |
} |
|
int printf(const char *fmt0, ...) |
{ |
register char *fmt; /* format string */ |
register int ch; /* character from fmt */ |
int n; /* handy integers (short term usage) */ |
register char *cp; /* handy char pointer (short term usage) */ |
register int flags; /* flags as above */ |
int ret; /* return value accumulator */ |
int width; /* width from format (%8d), or 0 */ |
int prec; /* precision from format (%.3d), or -1 */ |
char sign; /* sign prefix (' ', '+', '-', or \0) */ |
va_list ap; |
|
#ifdef FLOATING_POINT |
char *decimal_point = localeconv()->decimal_point; |
char softsign; /* temporary negative sign for floats */ |
/* |
* Although it is natural to declare this double here, the |
* declaration causes gcc to save FP registers even when not |
* printing an FP number. This results in surprising use |
* of FP registers to print integers or strings on at least the |
* PowerPC. A more proper solution would be to move FP printing |
* to another file, but this does seem to work. |
*/ |
#if 0 |
double _double; /* double precision arguments %[eEfgG] */ |
#else |
/* double precision arguments %[eEfgG] */ |
union { int i; double d; } _double_ = {0}; |
#define _double (_double_.d) |
#endif |
int expt; /* integer value of exponent */ |
int expsize; /* character count for expstr */ |
int ndig; /* actual number of digits returned by cvt */ |
char expstr[7]; /* buffer for exponent string */ |
#endif |
|
#ifndef _NO_LONGLONG |
#define quad_t long long |
#define u_quad_t unsigned long long |
#endif |
|
#ifndef _NO_LONGLONG |
u_quad_t _uquad; /* integer arguments %[diouxX] */ |
#else |
u_long _uquad; |
#endif |
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ |
int dprec; /* a copy of prec if [diouxX], 0 otherwise */ |
int realsz; /* field size expanded by dprec */ |
int size; /* size of converted field or string */ |
char *xdigs = (char *)0; /* digits for [xX] conversion */ |
#define NIOV 8 |
|
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ |
char ox[2]; /* space for 0x hex-prefix */ |
|
#define FLUSH() |
|
/* |
* To extend shorts properly, we need both signed and unsigned |
* argument extraction methods. |
*/ |
#ifndef _NO_LONGLONG |
#define SARG() \ |
(flags&QUADINT ? va_arg(ap, quad_t) : \ |
flags&LONGINT ? va_arg(ap, long) : \ |
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ |
(long)va_arg(ap, int)) |
#define UARG() \ |
(flags&QUADINT ? va_arg(ap, u_quad_t) : \ |
flags&LONGINT ? va_arg(ap, u_long) : \ |
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ |
(u_long)va_arg(ap, u_int)) |
#else |
#define SARG() \ |
(flags&LONGINT ? va_arg(ap, long) : \ |
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ |
(long)va_arg(ap, int)) |
#define UARG() \ |
(flags&LONGINT ? va_arg(ap, u_long) : \ |
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ |
(u_long)va_arg(ap, u_int)) |
#endif |
|
va_start (ap, fmt0); |
fmt = (char *)fmt0; |
ret = 0; |
|
/* |
* Scan the format for conversions (`%' character). |
*/ |
for (;;) { |
|
while (*fmt != 0 && *fmt != '%') { |
pc (*fmt); |
fmt++; |
ret++; |
} |
if (!*fmt) |
goto done; |
|
fmt++; /* Skip % */ |
flags = 0; |
dprec = 0; |
width = 0; |
prec = -1; |
sign = '\0'; |
|
rflag: ch = *fmt++; |
reswitch: switch (ch) { |
case ' ': |
/* |
* ``If the space and + flags both appear, the space |
* flag will be ignored.'' |
* -- ANSI X3J11 |
*/ |
if (!sign) |
sign = ' '; |
goto rflag; |
case '#': |
flags |= ALT; |
goto rflag; |
case '*': |
/* |
* ``A negative field width argument is taken as a |
* - flag followed by a positive field width.'' |
* -- ANSI X3J11 |
* They don't exclude field widths read from args. |
*/ |
if ((width = va_arg(ap, int)) >= 0) |
goto rflag; |
width = -width; |
/* FALLTHROUGH */ |
case '-': |
flags |= LADJUST; |
goto rflag; |
case '+': |
sign = '+'; |
goto rflag; |
case '.': |
if ((ch = *fmt++) == '*') { |
n = va_arg(ap, int); |
prec = n < 0 ? -1 : n; |
goto rflag; |
} |
n = 0; |
while (is_digit(ch)) { |
n = 10 * n + to_digit(ch); |
ch = *fmt++; |
} |
prec = n < 0 ? -1 : n; |
goto reswitch; |
case '0': |
/* |
* ``Note that 0 is taken as a flag, not as the |
* beginning of a field width.'' |
* -- ANSI X3J11 |
*/ |
flags |= ZEROPAD; |
goto rflag; |
case '1': case '2': case '3': case '4': |
case '5': case '6': case '7': case '8': case '9': |
n = 0; |
do { |
n = 10 * n + to_digit(ch); |
ch = *fmt++; |
} while (is_digit(ch)); |
width = n; |
goto reswitch; |
#ifdef FLOATING_POINT |
case 'L': |
flags |= LONGDBL; |
goto rflag; |
#endif |
case 'h': |
flags |= SHORTINT; |
goto rflag; |
case 'l': |
if (*fmt == 'l') { |
fmt++; |
flags |= QUADINT; |
} else { |
flags |= LONGINT; |
} |
goto rflag; |
case 'q': |
flags |= QUADINT; |
goto rflag; |
case 'c': |
*(cp = buf) = va_arg(ap, int); |
size = 1; |
sign = '\0'; |
break; |
case 'D': |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'd': |
case 'i': |
_uquad = SARG(); |
#ifndef _NO_LONGLONG |
if ((quad_t)_uquad < 0) |
#else |
if ((long) _uquad < 0) |
#endif |
{ |
|
_uquad = -_uquad; |
sign = '-'; |
} |
base = DEC; |
goto number; |
#ifdef FLOATING_POINT |
case 'e': |
case 'E': |
case 'f': |
case 'g': |
case 'G': |
if (prec == -1) { |
prec = DEFPREC; |
} else if ((ch == 'g' || ch == 'G') && prec == 0) { |
prec = 1; |
} |
|
if (flags & LONGDBL) { |
_double = (double) va_arg(ap, long double); |
} else { |
_double = va_arg(ap, double); |
} |
|
/* do this before tricky precision changes */ |
if (isinf(_double)) { |
if (_double < 0) |
sign = '-'; |
cp = "Inf"; |
size = 3; |
break; |
} |
if (isnan(_double)) { |
cp = "NaN"; |
size = 3; |
break; |
} |
|
flags |= FPT; |
cp = cvt(data, _double, prec, flags, &softsign, |
&expt, ch, &ndig); |
if (ch == 'g' || ch == 'G') { |
if (expt <= -4 || expt > prec) |
ch = (ch == 'g') ? 'e' : 'E'; |
else |
ch = 'g'; |
} |
if (ch <= 'e') { /* 'e' or 'E' fmt */ |
--expt; |
expsize = exponent(expstr, expt, ch); |
size = expsize + ndig; |
if (ndig > 1 || flags & ALT) |
++size; |
} else if (ch == 'f') { /* f fmt */ |
if (expt > 0) { |
size = expt; |
if (prec || flags & ALT) |
size += prec + 1; |
} else /* "0.X" */ |
size = prec + 2; |
} else if (expt >= ndig) { /* fixed g fmt */ |
size = expt; |
if (flags & ALT) |
++size; |
} else |
size = ndig + (expt > 0 ? |
1 : 2 - expt); |
|
if (softsign) |
sign = '-'; |
break; |
#endif /* FLOATING_POINT */ |
case 'n': |
#ifndef _NO_LONGLONG |
if (flags & QUADINT) |
*va_arg(ap, quad_t *) = ret; |
else |
#endif |
if (flags & LONGINT) |
*va_arg(ap, long *) = ret; |
else if (flags & SHORTINT) |
*va_arg(ap, short *) = ret; |
else |
*va_arg(ap, int *) = ret; |
continue; /* no output */ |
case 'O': |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'o': |
_uquad = UARG(); |
base = OCT; |
goto nosign; |
case 'p': |
/* |
* ``The argument shall be a pointer to void. The |
* value of the pointer is converted to a sequence |
* of printable characters, in an implementation- |
* defined manner.'' |
* -- ANSI X3J11 |
*/ |
/* NOSTRICT */ |
_uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *); |
base = HEX; |
xdigs = "0123456789abcdef"; |
flags |= HEXPREFIX; |
ch = 'x'; |
goto nosign; |
case 's': |
if ((cp = va_arg(ap, char *)) == NULL) |
cp = "(null)"; |
if (prec >= 0) { |
/* |
* can't use strlen; can only look for the |
* NUL in the first `prec' characters, and |
* strlen() will go further. |
*/ |
char *p = (char *)memchr(cp, 0, prec); |
|
if (p != NULL) { |
size = p - cp; |
if (size > prec) |
size = prec; |
} else |
size = prec; |
} else |
size = strlen(cp); |
sign = '\0'; |
break; |
case 'U': |
flags |= LONGINT; |
/*FALLTHROUGH*/ |
case 'u': |
_uquad = UARG(); |
base = DEC; |
goto nosign; |
case 'X': |
xdigs = "0123456789ABCDEF"; |
goto hex; |
case 'x': |
xdigs = "0123456789abcdef"; |
hex: _uquad = UARG(); |
base = HEX; |
/* leading 0x/X only if non-zero */ |
if (flags & ALT && _uquad != 0) |
flags |= HEXPREFIX; |
|
/* unsigned conversions */ |
nosign: sign = '\0'; |
/* |
* ``... diouXx conversions ... if a precision is |
* specified, the 0 flag will be ignored.'' |
* -- ANSI X3J11 |
*/ |
number: if ((dprec = prec) >= 0) |
flags &= ~ZEROPAD; |
|
/* |
* ``The result of converting a zero value with an |
* explicit precision of zero is no characters.'' |
* -- ANSI X3J11 |
*/ |
cp = buf + BUF; |
if (_uquad != 0 || prec != 0) { |
/* |
* Unsigned mod is hard, and unsigned mod |
* by a constant is easier than that by |
* a variable; hence this switch. |
*/ |
switch (base) { |
case OCT: |
do { |
*--cp = to_char(_uquad & 7); |
_uquad >>= 3; |
} while (_uquad); |
/* handle octal leading 0 */ |
if (flags & ALT && *cp != '0') |
*--cp = '0'; |
break; |
|
case DEC: |
/* many numbers are 1 digit */ |
while (_uquad >= 10) { |
*--cp = to_char(_uquad % 10); |
_uquad /= 10; |
} |
*--cp = to_char(_uquad); |
break; |
|
case HEX: |
do { |
*--cp = xdigs[_uquad & 15]; |
_uquad >>= 4; |
} while (_uquad); |
break; |
|
default: |
cp = "bug in vfprintf: bad base"; |
size = strlen(cp); |
goto skipsize; |
} |
} |
size = buf + BUF - cp; |
skipsize: |
break; |
default: /* "%?" prints ?, unless ? is NUL */ |
if (ch == '\0') |
goto done; |
/* pretend it was %c with argument ch */ |
cp = buf; |
*cp = ch; |
size = 1; |
sign = '\0'; |
break; |
} |
|
/* |
* All reasonable formats wind up here. At this point, `cp' |
* points to a string which (if not flags&LADJUST) should be |
* padded out to `width' places. If flags&ZEROPAD, it should |
* first be prefixed by any sign or other prefix; otherwise, |
* it should be blank padded before the prefix is emitted. |
* After any left-hand padding and prefixing, emit zeroes |
* required by a decimal [diouxX] precision, then print the |
* string proper, then emit zeroes required by any leftover |
* floating precision; finally, if LADJUST, pad with blanks. |
* |
* Compute actual size, so we know how much to pad. |
* size excludes decimal prec; realsz includes it. |
*/ |
realsz = dprec > size ? dprec : size; |
if (sign) |
realsz++; |
else if (flags & HEXPREFIX) |
realsz+= 2; |
|
/* right-adjusting blank padding */ |
if ((flags & (LADJUST|ZEROPAD)) == 0) |
PAD(width - realsz, blanks); |
|
/* prefix */ |
if (sign) { |
PRINT(&sign, 1); |
} else if (flags & HEXPREFIX) { |
ox[0] = '0'; |
ox[1] = ch; |
PRINT(ox, 2); |
} |
|
/* right-adjusting zero padding */ |
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) |
PAD(width - realsz, zeroes); |
|
/* leading zeroes from decimal precision */ |
PAD(dprec - size, zeroes); |
|
/* the string or number proper */ |
#ifdef FLOATING_POINT |
if ((flags & FPT) == 0) { |
PRINT(cp, size); |
} else { /* glue together f_p fragments */ |
if (ch >= 'f') { /* 'f' or 'g' */ |
if (_double == 0) { |
/* kludge for __dtoa irregularity */ |
PRINT("0", 1); |
if (expt < ndig || (flags & ALT) != 0) { |
PRINT(decimal_point, 1); |
PAD(ndig - 1, zeroes); |
} |
} else if (expt <= 0) { |
PRINT("0", 1); |
PRINT(decimal_point, 1); |
PAD(-expt, zeroes); |
PRINT(cp, ndig); |
} else if (expt >= ndig) { |
PRINT(cp, ndig); |
PAD(expt - ndig, zeroes); |
if (flags & ALT) |
PRINT(".", 1); |
} else { |
PRINT(cp, expt); |
cp += expt; |
PRINT(".", 1); |
PRINT(cp, ndig-expt); |
} |
} else { /* 'e' or 'E' */ |
if (ndig > 1 || flags & ALT) { |
ox[0] = *cp++; |
ox[1] = '.'; |
PRINT(ox, 2); |
if (_double || flags & ALT == 0) { |
PRINT(cp, ndig-1); |
} else /* 0.[0..] */ |
/* __dtoa irregularity */ |
PAD(ndig - 1, zeroes); |
} else /* XeYYY */ |
PRINT(cp, 1); |
PRINT(expstr, expsize); |
} |
} |
#else |
PRINT(cp, size); |
#endif |
/* left-adjusting padding (always blank) */ |
if (flags & LADJUST) |
PAD(width - realsz, blanks); |
|
/* finally, adjust ret */ |
ret += width > realsz ? width : realsz; |
|
FLUSH(); /* copy out the I/O vectors */ |
} |
done: |
va_end (ap); |
FLUSH(); |
return (ret); |
/* NOTREACHED */ |
} |
|
#ifdef FLOATING_POINT |
|
extern char *_dtoa_r _PARAMS((struct _reent *, double, int, |
int, int *, int *, char **)); |
|
static char * |
cvt(data, value, ndigits, flags, sign, decpt, ch, length) |
struct _reent *data; |
double value; |
int ndigits, flags, *decpt, ch, *length; |
char *sign; |
{ |
int mode, dsgn; |
char *digits, *bp, *rve; |
union double_union tmp; |
|
if (ch == 'f') { |
mode = 3; /* ndigits after the decimal point */ |
} else { |
/* To obtain ndigits after the decimal point for the 'e' |
* and 'E' formats, round to ndigits + 1 significant |
* figures. |
*/ |
if (ch == 'e' || ch == 'E') { |
ndigits++; |
} |
mode = 2; /* ndigits significant digits */ |
} |
|
tmp.d = value; |
if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */ |
value = -value; |
*sign = '-'; |
} else |
*sign = '\000'; |
digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve); |
if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */ |
bp = digits + ndigits; |
if (ch == 'f') { |
if (*digits == '0' && value) |
*decpt = -ndigits + 1; |
bp += *decpt; |
} |
if (value == 0) /* kludge for __dtoa irregularity */ |
rve = bp; |
while (rve < bp) |
*rve++ = '0'; |
} |
*length = rve - digits; |
return (digits); |
} |
|
static int |
exponent(p0, exp, fmtch) |
char *p0; |
int exp, fmtch; |
{ |
register char *p, *t; |
char expbuf[MAXEXP]; |
|
p = p0; |
*p++ = fmtch; |
if (exp < 0) { |
exp = -exp; |
*p++ = '-'; |
} |
else |
*p++ = '+'; |
t = expbuf + MAXEXP; |
if (exp > 9) { |
do { |
*--t = to_char(exp % 10); |
} while ((exp /= 10) > 9); |
*--t = to_char(exp); |
for (; t < expbuf + MAXEXP; *p++ = *t++); |
} |
else { |
*p++ = '0'; |
*p++ = to_char(exp); |
} |
return (p - p0); |
} |
#endif /* FLOATING_POINT */ |
/common/or32.S
0,0 → 1,149
.align 4 |
.global ___udivsi3 |
___udivsi3: |
l.addi r1,r1,-4 |
l.sw 0(r1),r9 |
l.addi r11,r0,0 |
l.addi r8,r4,0 |
l.addi r5,r3,0 |
l.sfne r8,r11 |
l.bnf 4f |
l.addi r7,r0,0 |
l.sfgtu r8,r5 |
l.bf 5f |
l.sfeq r8,r5 |
l.bf 6f |
l.sfltu r11,r8 |
l.bnf 2f |
l.addi r13,r0,32 |
l.movhi r9,hi(0x80000000) |
l.addi r6,r0,-1 |
1: |
l.and r3,r5,r9 |
l.slli r4,r7,1 |
l.addi r15,r5,0 |
l.srli r3,r3,31 |
l.add r13,r13,r6 |
l.or r7,r4,r3 |
l.sfltu r7,r8 |
l.bf 1b |
l.slli r5,r5,1 |
2: |
l.srli r7,r7,1 |
l.addi r13,r13,1 |
l.addi r9,r0,0 |
l.sfltu r9,r13 |
l.bnf 4f |
l.addi r5,r15,0 |
l.movhi r15,hi(0x80000000) |
l.addi r17,r0,0 |
3: |
l.and r3,r5,r15 |
l.slli r4,r7,1 |
l.srli r3,r3,31 |
l.or r7,r4,r3 |
l.sub r6,r7,r8 |
l.and r3,r6,r15 |
l.srli r3,r3,31 |
l.addi r4,r0,0 |
l.sfne r3,r4 |
l.bf 1f |
l.slli r3,r11,1 |
l.addi r4,r0,1 |
1: |
l.slli r5,r5,1 |
l.sfne r4,r17 |
l.bnf 2f |
l.or r11,r3,r4 |
l.addi r7,r6,0 |
2: |
l.addi r9,r9,1 |
l.sfltu r9,r13 |
l.bf 3b |
l.nop 0 |
l.j 4f |
l.nop 0 |
6: |
l.j 4f |
l.addi r11,r0,1 |
5: |
l.addi r7,r5,0 |
4: |
l.lwz r9,0(r1) |
l.jr r9 |
l.addi r1,r1,4 |
|
.align 4 |
.global ___divsi3 |
___divsi3: |
l.addi r1,r1,-8 |
l.sw 0(r1),r9 |
l.sw 4(r1),r10 |
l.addi r5,r3,0 |
l.addi r10,r0,0 |
l.sflts r5,r10 |
l.bnf 1f |
l.addi r3,r0,0 |
l.addi r10,r0,1 |
l.sub r5,r0,r5 |
1: |
l.sflts r4,r3 |
l.bnf 1f |
l.nop 0 |
l.addi r10,r10,1 |
l.sub r4,r0,r4 |
1: |
l.jal ___udivsi3 |
l.addi r3,r5,0 |
l.addi r3,r0,1 |
l.sfeq r10,r3 |
l.bnf 1f |
l.nop 0 |
l.sub r11,r0,r11 |
1: |
l.lwz r9,0(r1) |
l.lwz r10,4(r1) |
l.jr r9 |
l.addi r1,r1,8 |
|
.align 4 |
.global ___umodsi3 |
___umodsi3: |
l.addi r1,r1,-4 |
l.sw 0(r1),r9 |
l.jal ___udivsi3 |
l.nop 0 |
l.addi r11,r7,0 |
l.lwz r9,0(r1) |
l.jr r9 |
l.addi r1,r1,4 |
|
.align 4 |
.global ___modsi3 |
___modsi3: |
l.addi r1,r1,-8 |
l.sw 0(r1),r9 |
l.sw 4(r1),r10 |
l.sflts r3,r0 |
l.bnf 1f |
l.nop 0 |
l.addi r10,r0,1 |
l.sub r3,r0,r3 |
1: |
l.sflts r4,r0 |
l.bnf 1f |
l.nop 0 |
l.sub r4,r0,r4 |
1: |
l.jal ___udivsi3 |
l.nop 0 |
l.addi r3,r0,1 |
l.sfeq r10,r3 |
l.bnf 1f |
l.addi r11,r7,0 |
l.sub r11,r0,r11 |
1: |
l.lwz r9,0(r1) |
l.lwz r10,4(r1) |
l.jr r9 |
l.addi r1,r1,8 |
/common/font.c
0,0 → 1,309
#include "common.h" |
#if CRT_ENABLED |
|
unsigned char font[256][12] = { |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0, 00h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1, 01h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2, 02h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3, 03h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4, 04h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 5, 05h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 6, 06h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 7, 07h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 8, 08h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 9, 09h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 10, 0ah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 11, 0bh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 12, 0ch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 13, 0dh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14, 0eh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15, 0fh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16, 10h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17, 11h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 18, 12h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 19, 13h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 20, 14h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 21, 15h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 22, 16h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 23, 17h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 24, 18h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 25, 19h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 26, 1ah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 27, 1bh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 28, 1ch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 29, 1dh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 30, 1eh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 31, 1fh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 32, 20h, ' ' */ |
{0x00, 0x0c, 0x1e, 0x1e, 0x1e, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 33, 21h, '!' */ |
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 34, 22h, '"' */ |
{0x00, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x00, 0x00}, /* 35, 23h, '#' */ |
{0x0c, 0x0c, 0x3e, 0x03, 0x03, 0x1e, 0x30, 0x30, 0x1f, 0x0c, 0x0c, 0x00}, /* 36, 24h, '$' */ |
{0x00, 0x00, 0x00, 0x23, 0x33, 0x18, 0x0c, 0x06, 0x33, 0x31, 0x00, 0x00}, /* 37, 25h, '%' */ |
{0x00, 0x0e, 0x1b, 0x1b, 0x0e, 0x5f, 0x7b, 0x33, 0x3b, 0x6e, 0x00, 0x00}, /* 38, 26h, '&' */ |
{0x00, 0x0c, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 39, 27h, ''' */ |
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 40, 28h, '(' */ |
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 41, 29h, ')' */ |
{0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00}, /* 42, 2ah, '*' */ |
{0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 43, 2bh, '+' */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x06, 0x00}, /* 44, 2ch, ',' */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 45, 2dh, '-' */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00}, /* 46, 2eh, '.' */ |
{0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00}, /* 47, 2fh, '/' */ |
{0x00, 0x3e, 0x63, 0x73, 0x7b, 0x6b, 0x6f, 0x67, 0x63, 0x3e, 0x00, 0x00}, /* 48, 30h, '0' */ |
{0x00, 0x08, 0x0c, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00}, /* 49, 31h, '1' */ |
{0x00, 0x1e, 0x33, 0x33, 0x30, 0x18, 0x0c, 0x06, 0x33, 0x3f, 0x00, 0x00}, /* 50, 32h, '2' */ |
{0x00, 0x1e, 0x33, 0x30, 0x30, 0x1c, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 51, 33h, '3' */ |
{0x00, 0x30, 0x38, 0x3c, 0x36, 0x33, 0x7f, 0x30, 0x30, 0x78, 0x00, 0x00}, /* 52, 34h, '4' */ |
{0x00, 0x3f, 0x03, 0x03, 0x03, 0x1f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00}, /* 53, 35h, '5' */ |
{0x00, 0x1c, 0x06, 0x03, 0x03, 0x1f, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 54, 36h, '6' */ |
{0x00, 0x7f, 0x63, 0x63, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x00, 0x00}, /* 55, 37h, '7' */ |
{0x00, 0x1e, 0x33, 0x33, 0x37, 0x1e, 0x3b, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 56, 38h, '8' */ |
{0x00, 0x1e, 0x33, 0x33, 0x33, 0x3e, 0x18, 0x18, 0x0c, 0x0e, 0x00, 0x00}, /* 57, 39h, '9' */ |
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00}, /* 58, 3ah, ':' */ |
{0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x18, 0x0c, 0x00}, /* 59, 3bh, ';' */ |
{0x00, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00}, /* 60, 3ch, '<' */ |
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 61, 3dh, '=' */ |
{0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00}, /* 62, 3eh, '>' */ |
{0x00, 0x1e, 0x33, 0x30, 0x18, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x00, 0x00}, /* 63, 3fh, '?' */ |
{0x00, 0x3e, 0x63, 0x63, 0x7b, 0x7b, 0x7b, 0x03, 0x03, 0x3e, 0x00, 0x00}, /* 64, 40h, '@' */ |
{0x00, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 65, 41h, 'A' */ |
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x66, 0x3f, 0x00, 0x00}, /* 66, 42h, 'B' */ |
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x03, 0x63, 0x66, 0x3c, 0x00, 0x00}, /* 67, 43h, 'C' */ |
{0x00, 0x1f, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1f, 0x00, 0x00}, /* 68, 44h, 'D' */ |
{0x00, 0x7f, 0x46, 0x06, 0x26, 0x3e, 0x26, 0x06, 0x46, 0x7f, 0x00, 0x00}, /* 69, 45h, 'E' */ |
{0x00, 0x7f, 0x66, 0x46, 0x26, 0x3e, 0x26, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 70, 46h, 'F' */ |
{0x00, 0x3c, 0x66, 0x63, 0x03, 0x03, 0x73, 0x63, 0x66, 0x7c, 0x00, 0x00}, /* 71, 47h, 'G' */ |
{0x00, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 72, 48h, 'H' */ |
{0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 73, 49h, 'I' */ |
{0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 74, 4ah, 'J' */ |
{0x00, 0x67, 0x66, 0x36, 0x36, 0x1e, 0x36, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 75, 4bh, 'K' */ |
{0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x66, 0x7f, 0x00, 0x00}, /* 76, 4ch, 'L' */ |
{0x00, 0x63, 0x77, 0x7f, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00}, /* 77, 4dh, 'M' */ |
{0x00, 0x63, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x00, 0x00}, /* 78, 4eh, 'N' */ |
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00}, /* 79, 4fh, 'O' */ |
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 80, 50h, 'P' */ |
{0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x73, 0x7b, 0x3e, 0x30, 0x78, 0x00}, /* 81, 51h, 'Q' */ |
{0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x36, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 82, 52h, 'R' */ |
{0x00, 0x1e, 0x33, 0x33, 0x03, 0x0e, 0x18, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 83, 53h, 'S' */ |
{0x00, 0x3f, 0x2d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 84, 54h, 'T' */ |
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 85, 55h, 'U' */ |
{0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 86, 56h, 'V' */ |
{0x00, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x36, 0x00, 0x00}, /* 87, 57h, 'W' */ |
{0x00, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x1e, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 88, 58h, 'X' */ |
{0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00}, /* 89, 59h, 'Y' */ |
{0x00, 0x7f, 0x73, 0x19, 0x18, 0x0c, 0x06, 0x46, 0x63, 0x7f, 0x00, 0x00}, /* 90, 5ah, 'Z' */ |
{0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00}, /* 91, 5bh, '[' */ |
{0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00}, /* 92, 5ch, '\' */ |
{0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00}, /* 93, 5dh, ']' */ |
{0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 94, 5eh, '^' */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00}, /* 95, 5fh, '_' */ |
{0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 96, 60h, '`' */ |
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 97, 61h, 'a' */ |
{0x00, 0x07, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3b, 0x00, 0x00}, /* 98, 62h, 'b' */ |
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x03, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 99, 63h, 'c' */ |
{0x00, 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 100, 64h, 'd' */ |
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x3f, 0x03, 0x33, 0x1e, 0x00, 0x00}, /* 101, 65h, 'e' */ |
{0x00, 0x1c, 0x36, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 102, 66h, 'f' */ |
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x33, 0x1e}, /* 103, 67h, 'g' */ |
{0x00, 0x07, 0x06, 0x06, 0x36, 0x6e, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00}, /* 104, 68h, 'h' */ |
{0x00, 0x18, 0x18, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 105, 69h, 'i' */ |
{0x00, 0x30, 0x30, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1e}, /* 106, 6ah, 'j' */ |
{0x00, 0x07, 0x06, 0x06, 0x66, 0x36, 0x1e, 0x36, 0x66, 0x67, 0x00, 0x00}, /* 107, 6bh, 'k' */ |
{0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00}, /* 108, 6ch, 'l' */ |
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x6b, 0x6b, 0x6b, 0x6b, 0x63, 0x00, 0x00}, /* 109, 6dh, 'm' */ |
{0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00}, /* 110, 6eh, 'n' */ |
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00}, /* 111, 6fh, 'o' */ |
{0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0f}, /* 112, 70h, 'p' */ |
{0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x78}, /* 113, 71h, 'q' */ |
{0x00, 0x00, 0x00, 0x00, 0x37, 0x76, 0x6e, 0x06, 0x06, 0x0f, 0x00, 0x00}, /* 114, 72h, 'r' */ |
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x06, 0x18, 0x33, 0x1e, 0x00, 0x00}, /* 115, 73h, 's' */ |
{0x00, 0x00, 0x04, 0x06, 0x3f, 0x06, 0x06, 0x06, 0x36, 0x1c, 0x00, 0x00}, /* 116, 74h, 't' */ |
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00}, /* 117, 75h, 'u' */ |
{0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x0c, 0x00, 0x00}, /* 118, 76h, 'v' */ |
{0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x6b, 0x6b, 0x36, 0x36, 0x00, 0x00}, /* 119, 77h, 'w' */ |
{0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1c, 0x1c, 0x36, 0x63, 0x00, 0x00}, /* 120, 78h, 'x' */ |
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x30, 0x18, 0x0f}, /* 121, 79h, 'y' */ |
{0x00, 0x00, 0x00, 0x00, 0x3f, 0x31, 0x18, 0x06, 0x23, 0x3f, 0x00, 0x00}, /* 122, 7ah, 'z' */ |
{0x00, 0x38, 0x0c, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x0c, 0x38, 0x00, 0x00}, /* 123, 7bh, '{' */ |
{0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00}, /* 124, 7ch, '|' */ |
{0x00, 0x07, 0x0c, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x0c, 0x07, 0x00, 0x00}, /* 125, 7dh, '}' */ |
{0x00, 0xce, 0x5b, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 126, 7eh, '~' */ |
{0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x00, 0x00, 0x00}, /* 127, 7fh, '' */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 128, 80h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 129, 81h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 130, 82h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 131, 83h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 132, 84h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 133, 85h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 134, 86h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 135, 87h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 136, 88h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 137, 89h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 138, 8ah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 139, 8bh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 140, 8ch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 141, 8dh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 142, 8eh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 143, 8fh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 144, 90h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 145, 91h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 146, 92h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 147, 93h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 148, 94h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 149, 95h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 150, 96h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 151, 97h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 152, 98h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 153, 99h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 154, 9ah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 155, 9bh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 156, 9ch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 157, 9dh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 158, 9eh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 159, 9fh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 160, a0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 161, a1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 162, a2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 163, a3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 164, a4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 165, a5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 166, a6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 167, a7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 168, a8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 169, a9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 170, aah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 171, abh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 172, ach */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 173, adh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 174, aeh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 175, afh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 176, b0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 177, b1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 178, b2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 179, b3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 180, b4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 181, b5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 182, b6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 183, b7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 184, b8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 185, b9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 186, bah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 187, bbh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 188, bch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 189, bdh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 190, beh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 191, bfh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 192, c0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 193, c1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 194, c2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 195, c3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 196, c4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 197, c5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 198, c6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 199, c7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 200, c8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 201, c9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 202, cah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 203, cbh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 204, cch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 205, cdh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 206, ceh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 207, cfh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 208, d0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 209, d1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 210, d2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 211, d3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 212, d4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 213, d5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 214, d6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 215, d7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 216, d8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 217, d9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 218, dah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 219, dbh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 220, dch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 221, ddh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 222, deh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 223, dfh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 224, e0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 225, e1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 226, e2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 227, e3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 228, e4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 229, e5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 230, e6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 231, e7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 232, e8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 233, e9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 234, eah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 235, ebh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 236, ech */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 237, edh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 238, eeh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 239, efh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 240, f0h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 241, f1h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 242, f2h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 243, f3h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 244, f4h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 245, f5h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 246, f6h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 247, f7h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 248, f8h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 249, f9h */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 250, fah */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 251, fbh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 252, fch */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 253, fdh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 254, feh */ |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};/* 255, ffh */ |
|
#endif /* CRT_ENABLED */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/common/common.c
0,0 → 1,261
#include "common.h" |
#include "uart.h" |
#include "screen.h" |
#include "support.h" |
|
#define MAX_COMMANDS 100 |
|
bd_t bd; |
|
int num_commands = 0; |
|
struct command_struct { |
const char *name; |
const char *params; |
const char *help; |
int (*func)(int argc, char *argv[]); |
} command[MAX_COMMANDS]; |
|
unsigned long strtoul(char *s) |
{ |
int base = 10; |
char *ptmp; |
unsigned long val = 0; |
unsigned long digit = 1; |
|
ptmp = s; |
while (*ptmp != '\0') |
if (*ptmp++ == 'x') |
base = 16; |
|
while (ptmp-- != s) |
if ((*ptmp >= '0') && |
(*ptmp <= '9')) |
{ |
val += (*ptmp - '0') * digit; |
digit *= base; |
} |
else |
if ((*ptmp >= 'a') && |
(*ptmp <= 'f')) |
{ |
val += (*ptmp - 'a' + 10) * digit; |
digit *= base; |
} |
|
return val; |
} |
|
void putc (const char c) |
{ |
debug ("getc %i, %i = %c\n", bd.bi_console_type, c, c); |
switch (bd.bi_console_type) { |
case CT_NONE: |
break; |
case CT_UART: |
uart_putc (c); |
break; |
case CT_CRT: |
screen_putc (c); |
break; |
case CT_SIM: |
__printf ("%c", c); |
break; |
} |
} |
|
int getc () |
{ |
debug ("getc %i\n", bd.bi_console_type); |
switch (bd.bi_console_type) { |
case CT_NONE: |
case CT_CRT: |
case CT_SIM: |
return -1; |
case CT_UART: |
return uart_getc (); |
} |
return -1; |
} |
|
int testc () |
{ |
debug ("testc %i\n", bd.bi_console_type); |
switch (bd.bi_console_type) { |
case CT_NONE: |
case CT_CRT: |
case CT_SIM: |
return -1; |
case CT_UART: |
return uart_testc (); |
} |
return -1; |
} |
|
int ctrlc () |
{ |
if (testc ()) { |
switch (getc ()) { |
case 0x03: /* ^C - Control C */ |
return 1; |
default: |
break; |
} |
} |
return 0; |
} |
|
void change_console_type (enum bi_console_type_t con_type) |
{ |
debug ("Console change %i -> %i\n", bd.bi_console_type, con_type); |
/* Close previous */ |
switch (bd.bi_console_type) { |
case CT_NONE: |
case CT_UART: |
case CT_CRT: |
case CT_SIM: |
break; |
} |
bd.bi_console_type = con_type; |
/* Initialize new */ |
switch (bd.bi_console_type) { |
case CT_NONE: |
break; |
case CT_UART: |
uart_init (); |
break; |
case CT_CRT: |
screen_init (); |
break; |
case CT_SIM: |
break; |
} |
} |
|
void register_command_func (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[])) |
{ |
debug ("register_command '%s'\n", name); |
if (num_commands < MAX_COMMANDS) { |
command[num_commands].name = name; |
command[num_commands].params = params; |
command[num_commands].help = help; |
command[num_commands].func = func; |
num_commands++; |
} else printf ("Command '%s' ignored; MAX_COMMANDS limit reached\n", name); |
} |
|
/* Process command and arguments by executing |
specific function. */ |
void mon_command(void) |
{ |
char c = '\0'; |
char str[1000]; |
char *pstr = str; |
char *command_str; |
char *argv[20]; |
int argc = 0; |
int end = 0; |
|
/* Show prompt */ |
#ifdef XESS |
printf ("\norp-xsv> "); |
#else |
printf ("\nbender> "); |
#endif |
|
/* Get characters from UART */ |
c = getc(); |
while (c != '\r' && c != '\f' && c != '\n') |
{ |
if (c == '\b') |
pstr--; |
else |
*pstr++ = c; |
putc(c); |
c = getc(); |
} |
*pstr = '\0'; |
printf ("\n"); |
|
/* Skip leading blanks */ |
pstr = str; |
while (*pstr == ' ' && *pstr != '\0') pstr++; |
|
/* Get command from the string */ |
command_str = pstr; |
while (*pstr != '\0' && *pstr != ' ') pstr++; |
if (*pstr == '\0') end = 1; |
*pstr = '\0'; |
|
while (!end) { |
/* Go to next argument */ |
while (*pstr == ' ' && *pstr != '\0') pstr++; |
if (*pstr) argv[argc++] = pstr; |
else end = 1; |
} |
|
{ |
int i, found = 0; |
for (i = 0; i < num_commands; i++) |
if (strcmp (command_str, command[i].name) == 0) { |
switch (command[i].func (argc, &argv[0])) { |
case -1: |
printf ("Missing/wrong parameters, usage: %s %s\n", command[i].name, command[i].params); |
break; |
} |
found = 1; |
break; |
} |
if (!found) printf ("Unknown command. Type 'help' for help.\n"); |
} |
} |
|
#if HELP_ENABLED |
/* Displays help screen */ |
int help_cmd (int argc, char *argv[]) |
{ |
int i; |
for (i = 0; i < num_commands; i++) |
printf ("%-10s %-20s - %s\n", command[i].name, command[i].params, command[i].help); |
return 0; |
} |
#endif /* HELP_ENABLED */ |
|
void module_cpu_init (void); |
void module_memory_init (void); |
void module_eth_init (void); |
//void module_dhry_init (void); |
void module_camera_init (void); |
void module_tftp_init (void); |
void tick_init(void); |
|
/* List of all initializations */ |
void mon_init (void) |
{ |
module_cpu_init (); |
module_memory_init (); |
module_eth_init (); |
// module_dhry_init (); |
module_camera_init (); |
module_tftp_init (); |
|
// tick_init(); |
} |
|
/* Main shell loop */ |
int main(int argc, char **argv) |
{ |
/* Initialize controller */ |
change_console_type (CT_UART); |
mon_init (); |
|
if (HELP_ENABLED) register_command ("help", "", "shows this help", help_cmd); |
|
#ifdef XESS |
printf ("\nORP-XSV Monitor (type 'help' for help)\n"); |
#else |
printf ("\nBender Monitor (type 'help' for help)\n"); |
#endif |
|
while(1) mon_command(); |
} |
/common/int.c
0,0 → 1,79
/* This file is part of test microkernel for OpenRISC 1000. */ |
/* (C) 2001 Simon Srot, srot@opencores.org */ |
|
#include "support.h" |
#include "spr_defs.h" |
#include "int.h" |
|
#ifdef OR1K |
|
/* Interrupt handlers table */ |
struct ihnd int_handlers[MAX_INT_HANDLERS]; |
|
/* Initialize routine */ |
int int_init() |
{ |
int i; |
|
for(i = 0; i < MAX_INT_HANDLERS; i++) { |
int_handlers[i].handler = 0; |
int_handlers[i].arg = 0; |
} |
|
return 0; |
} |
|
/* Add interrupt handler */ |
int int_add(unsigned long vect, void (* handler)(void *), void *arg) |
{ |
if(vect >= MAX_INT_HANDLERS) |
return -1; |
|
int_handlers[vect].handler = handler; |
int_handlers[vect].arg = arg; |
|
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect)); |
|
return 0; |
} |
|
/* Disable interrupt */ |
int int_disable(unsigned long vect) |
{ |
if(vect >= MAX_INT_HANDLERS) |
return -1; |
|
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << vect)); |
|
return 0; |
} |
|
/* Enable interrupt */ |
int int_enable(unsigned long vect) |
{ |
if(vect >= MAX_INT_HANDLERS) |
return -1; |
|
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect)); |
|
return 0; |
} |
|
/* Main interrupt handler */ |
void int_main() |
{ |
unsigned long picsr = mfspr(SPR_PICSR); |
unsigned long i = 0; |
|
mtspr(SPR_PICSR, 0); |
|
while(i < 32) { |
if((picsr & (0x01L << i)) && (int_handlers[i].handler != 0)) { |
(*int_handlers[i].handler)(int_handlers[i].arg); |
mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(0x00000001L << i)); |
} |
i++; |
} |
} |
|
#endif |
/common/Makefile
0,0 → 1,22
|
# CFLAGS += -DET_DEBUG -DDEBUG |
|
LIB = common_o.o |
|
OBJS = common.o support.o cprintf.o screen.o font.o |
SOBJS = or32.o |
|
all: $(LIB) |
|
$(LIB): $(OBJS) $(SOBJS) |
$(LD) -r -o $@ $(OBJS) $(SOBJS) |
|
######################################################################### |
|
.depend: Makefile $(OBJS:.o=.c) $(SOBJS:.o=.S) |
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@ |
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) > $@ |
|
sinclude .depend |
|
######################################################################### |
/common/support.c
0,0 → 1,134
/* Support */ |
|
#include <sys/time.h> |
#include "spr_defs.h" |
#include "support.h" |
#include "int.h" |
|
unsigned long timestamp = 0; |
|
void int_main(void); |
|
/* return value by making a syscall */ |
void exit (int i) |
{ |
asm("l.add r3,r0,%0": : "r" (i)); |
asm("l.nop %0": :"K" (NOP_EXIT)); |
while (1); |
} |
|
/* activate printf support in simulator */ |
void __printf(const char *fmt, ...) |
{ |
|
va_list args; |
va_start(args, fmt); |
__asm__ __volatile__ (" l.addi\tr3,%1,0\n \ |
l.addi\tr4,%2,0\n \ |
l.nop %0": :"K" (NOP_PRINTF), "r" (fmt), "r" (args) : "r3", "r4"); |
} |
|
/* print long */ |
void report(unsigned long value) |
{ |
asm("l.addi\tr3,%0,0": :"r" (value)); |
asm("l.nop %0": :"K" (NOP_REPORT)); |
} |
|
/* just to satisfy linker */ |
void __main(void) |
{ |
} |
|
/* For writing into SPR. */ |
void mtspr(unsigned long spr, unsigned long value) |
{ |
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value)); |
} |
|
/* For reading SPR. */ |
unsigned long mfspr(unsigned long spr) |
{ |
unsigned long value; |
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr)); |
return value; |
} |
|
void *memcpy (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length) |
{ |
char *dst = dstvoid; |
const char *src = (const char *) srcvoid; |
|
while (length--) |
*dst++ = *src++; |
return dst; |
} |
|
int memcmp (void *__restrict dstvoid, |
__const void *__restrict srcvoid, size_t length) |
{ |
char *dst = dstvoid; |
const char *src = (const char *) srcvoid; |
|
while (length--) |
if(*dst++ != *src++) |
if(*(--dst) > *(--src)) |
return 1; |
else |
return -1; |
return 1; |
} |
|
|
void *memchr (void *__restrict dstvoid, |
__const char data, size_t length) |
{ |
char *dst = dstvoid; |
|
while (length--) *dst++ = data; |
return dst; |
} |
|
int strlen (__const char *srcvoid) |
{ |
int len = 0; |
while (*srcvoid++) len++; |
return len; |
} |
|
int strcmp (const char *s1, const char *s2) |
{ |
|
while (*s1 != '\0' && *s1 == *s2) { |
s1++; |
s2++; |
} |
|
return (*(unsigned char *) s1) - (*(unsigned char *) s2); |
} |
|
char *strcpy (char *dst0, char *src0) |
{ |
char *s = dst0; |
|
while ((*dst0++ = *src0++)); |
|
return s; |
} |
|
void reset_timer (void) |
{ |
timestamp = 0; |
} |
|
unsigned long get_timer (unsigned long base) |
{ |
return (timestamp - base); |
} |
|
void set_timer (unsigned long t) |
{ |
timestamp = t; |
} |
|
/config.mk
0,0 → 1,51
######################################################################### |
|
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ |
else if [ -x /bin/bash ]; then echo /bin/bash; \ |
else echo sh; fi ; fi) |
|
HOSTCC = cc |
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer |
|
######################################################################### |
|
# |
# Include the make variables (CC, etc...) |
# |
AS = $(CROSS_COMPILE)as |
LD = $(CROSS_COMPILE)ld |
CC = $(CROSS_COMPILE)gcc |
AR = $(CROSS_COMPILE)ar |
NM = $(CROSS_COMPILE)nm |
STRIP = $(CROSS_COMPILE)strip |
OBJCOPY = $(CROSS_COMPILE)objcopy |
OBJDUMP = $(CROSS_COMPILE)objdump |
RANLIB = $(CROSS_COMPILE)ranlib |
|
CFLAGS += -I$(TOPDIR)/include -DOR1K -Wall -Wstrict-prototypes -Werror-implicit-function-declaration -fomit-frame-pointer -fno-strength-reduce -O2 -g -pipe -fno-builtin -nostdlib |
|
######################################################################### |
|
export CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE \ |
AS LD CC AR NM STRIP OBJCOPY OBJDUMP \ |
MAKE CFLAGS AFLAGS |
|
######################################################################### |
|
%.s: %.S |
$(CPP) $(AFLAGS) -o $@ $(CURDIR)/$< |
%.o: %.S |
$(CC) $(AFLAGS) -c -o $@ $(CURDIR)/$< |
%.o: %.c |
$(CC) $(CFLAGS) -c -o $@ $< |
|
%.bin: %.or32 |
or32-rtems-objcopy -O binary $< $@ |
|
%.img: %.bin |
utils/bin2flimg 1 $< > $@ |
|
%.srec: %.bin |
utils/bin2srec $< > $@ |
|
######################################################################### |
/flash.ld
0,0 → 1,55
MEMORY |
{ |
flash : ORIGIN = 0x04000000, LENGTH = 0x00100000 |
vectors : ORIGIN = 0x00000000, LENGTH = 0x00002000 |
ram : ORIGIN = 0x00002000, LENGTH = 0x00200000 - 0x00002000 |
} |
|
SECTIONS |
{ |
.reset : |
{ |
*(.reset) |
} > flash |
|
.text ALIGN(0x04): |
{ |
*(.text) |
} > flash |
|
.rodata : |
{ |
*(.rodata) |
} > flash |
|
.dummy ALIGN(0x04): |
{ |
_src_beg = .; |
} |
|
.vectors : |
AT ( ADDR (.dummy) ) |
{ |
_vec_start = .; |
*(.vectors) |
_vec_end = .; |
} > vectors |
|
.data : |
AT ( ADDR (.dummy) + SIZEOF (.vectors) ) |
{ |
_dst_beg = .; |
*(.data) |
_dst_end = .; |
} > ram |
|
.bss : |
{ |
*(.bss) |
} > ram |
|
.stack : |
{ |
*(.stack) |
} > ram |
} |
/Makefile
0,0 → 1,65
ifndef CROSS_COMPILE |
CROSS_COMPILE = or32-uclinux- |
endif |
|
export CROSS_COMPILE |
|
######################################################################### |
|
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) |
export TOPDIR |
|
include $(TOPDIR)/config.mk |
|
# order is important here: |
SUBDIRS = drivers common cmds services |
|
LIBS = common/common_o.o cmds/cmds.o services/services.o drivers/drivers.o |
|
######################################################################### |
|
all: orpmon.or32 orpmon-flash.or32 |
|
reset.o: reset.S Makefile |
$(CC) -c -o $@ $< $(CFLAGS) -DIN_FLASH=0 |
|
reset-flash.o: reset.S Makefile |
$(CC) -c -o $@ $< $(CFLAGS) -DIN_FLASH=1 |
|
orpmon.or32: depend subdirs reset.o $(LIBS) Makefile |
$(LD) -Tram.ld -o $@ reset.o $(LIBS) |
|
orpmon-flash.or32: depend subdirs reset-flash.o $(LIBS) Makefile |
$(LD) -Tflash.ld -o $@ reset-flash.o $(LIBS) |
|
System.map: orpmon.or32 |
|
@$(NM) $< | \ |
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ |
sort > System.map |
|
######################################################################### |
|
depend dep: |
@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir .depend ; done |
|
subdirs: |
@for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir || exit 1 ; done |
|
clean: |
find . -type f \ |
\( -name 'core' -o -name '*.bak' -o -name '*~' \ |
-o -name '*.o' -o -name '*.a' \ |
-o -name '*.or32' -o -name '*.bin' -o -name '*.srec' \ |
-o -name '*.mem' -o -name '*.img' \) -print \ |
| xargs rm -f |
rm -f System.map |
|
distclean: clean |
find . -type f \ |
\( -name .depend -o -name '*.srec' -o -name '*.bin' \) \ |
-print | xargs rm -f |
rm -f $(OBJS) *.bak tags TAGS |
rm -fr *.*~ |
|
######################################################################### |
/ram.ld
0,0 → 1,38
MEMORY |
{ |
vectors : ORIGIN = 0x00000000, LENGTH = 0x00002000 |
ram : ORIGIN = 0x00002000, LENGTH = 0x00200000 - 0x00002000 |
} |
|
SECTIONS |
{ |
.vectors : |
{ |
*(.vectors) |
} > vectors |
|
.text : |
{ |
*(.text) |
} > ram |
|
.data : |
{ |
*(.data) |
} > ram |
|
.rodata : |
{ |
*(.rodata) |
} > ram |
|
.bss : |
{ |
*(.bss) |
} > ram |
|
.stack : |
{ |
*(.stack) |
} > ram |
} |
/drivers/eth.c
0,0 → 1,246
#include "common.h" |
#include "support.h" |
#include "board.h" |
#include "uart.h" |
#include "eth.h" |
#include "spr_defs.h" |
|
extern int printf (const char *fmt, ...); |
extern void lolev_ie(void); |
extern void lolev_idis(void); |
|
int tx_next; /* Next buffer to be given to the user */ |
int tx_last; /* Next buffer to be checked if packet sent */ |
int tx_full; |
int rx_next; /* Next buffer to be checked for new packet and given to the user */ |
void (*receive)(void *add, int len); /* Pointer to function to be called |
when frame is received */ |
|
void init_tx_bd_pool(void) |
{ |
eth_bd *bd; |
int i; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
for(i = 0; i < ETH_TXBD_NUM; i++){ |
|
/* Set Tx BD status */ |
bd[i].status = ETH_TX_BD_PAD | ETH_TX_BD_CRC | ETH_RX_BD_IRQ; |
|
/* Initialize Tx buffer pointer */ |
bd[i].addr = ETH_DATA_BASE + i * ETH_MAXBUF_LEN; |
} |
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Tx BD - Wrap |
} |
|
void init_rx_bd_pool(void) |
{ |
eth_bd *bd; |
int i; |
|
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM; |
|
for(i = 0; i < ETH_RXBD_NUM; i++){ |
|
/* Set Tx BD status */ |
bd[i].status = ETH_RX_BD_EMPTY | ETH_RX_BD_IRQ; |
|
/* Initialize Tx buffer pointer */ |
bd[i].addr = ETH_DATA_BASE + (ETH_TXBD_NUM + i) * ETH_MAXBUF_LEN; |
} |
|
bd[i-1].status |= ETH_TX_BD_WRAP; // Last Rx BD - Wrap |
} |
|
void eth_init (void (*rec)(volatile unsigned char *, int)) |
{ |
|
/* Reset ethernet core */ |
REG32(ETH_REG_BASE + ETH_MODER) = ETH_MODER_RST; /* Reset ON */ |
REG32(ETH_REG_BASE + ETH_MODER) &= ~ETH_MODER_RST; /* Reset OFF */ |
|
/* Setting TX BD number */ |
REG32(ETH_REG_BASE + ETH_TX_BD_NUM) = ETH_TXBD_NUM << 1; |
|
/* Set min/max packet length */ |
REG32(ETH_REG_BASE + ETH_PACKETLEN) = 0x003c0600; |
|
/* Set IPGT register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGT) = 0x00000012; |
|
/* Set IPGR1 register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGR1) = 0x0000000c; |
|
/* Set IPGR2 register to recomended value */ |
REG32(ETH_REG_BASE + ETH_IPGR2) = 0x00000012; |
|
/* Set COLLCONF register to recomended value */ |
REG32(ETH_REG_BASE + ETH_COLLCONF) = 0x0000003f; |
|
#if 0 |
REG32(ETH_REG_BASE + ETH_CTRLMODER) = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW; |
#else |
REG32(ETH_REG_BASE + ETH_CTRLMODER) = 0; |
#endif |
|
/* Initialize RX and TX buffer descriptors */ |
init_rx_bd_pool(); |
init_tx_bd_pool(); |
|
/* Initialize tx pointers */ |
tx_next = 0; |
tx_last = 0; |
tx_full = 0; |
|
/* Initialize rx pointers */ |
rx_next = 0; |
receive = rec; |
|
/* Set local MAC address */ |
REG32(ETH_REG_BASE + ETH_MAC_ADDR1) = ETH_MACADDR0 << 8 | |
ETH_MACADDR1; |
REG32(ETH_REG_BASE + ETH_MAC_ADDR0) = ETH_MACADDR2 << 24 | |
ETH_MACADDR3 << 16 | |
ETH_MACADDR4 << 8 | |
ETH_MACADDR5; |
|
/* Clear all pending interrupts */ |
REG32(ETH_REG_BASE + ETH_INT) = 0xffffffff; |
|
/* Promisc, IFG, CRCEn */ |
REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_PAD | ETH_MODER_IFG | ETH_MODER_CRCEN; |
|
/* Enable interrupt sources */ |
#if 0 |
regs->int_mask = ETH_INT_MASK_TXB | |
ETH_INT_MASK_TXE | |
ETH_INT_MASK_RXF | |
ETH_INT_MASK_RXE | |
ETH_INT_MASK_BUSY | |
ETH_INT_MASK_TXC | |
ETH_INT_MASK_RXC; |
#endif |
|
/* Enable receiver and transmiter */ |
REG32(ETH_REG_BASE + ETH_MODER) |= ETH_MODER_RXEN | ETH_MODER_TXEN; |
|
} |
|
/* Returns pointer to next free buffer; NULL if none available */ |
void *eth_get_tx_buf () |
{ |
eth_bd *bd; |
unsigned long add; |
|
if(tx_full) |
return (void *)0; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
if(bd[tx_next].status & ETH_TX_BD_READY) |
return (void *)0; |
|
add = bd[tx_next].addr; |
|
tx_next = (tx_next + 1) & ETH_TXBD_NUM_MASK; |
|
if(tx_next == tx_last) |
tx_full = 1; |
|
return (void *)add; |
} |
|
/* Send a packet at address */ |
void eth_send (void *buf, unsigned long len) |
{ |
eth_bd *bd; |
|
bd = (eth_bd *)ETH_BD_BASE; |
|
bd[tx_last].addr = (unsigned long)buf; |
|
bd[tx_last].status &= ~ETH_TX_BD_STATS; |
bd[tx_last].status |= ETH_TX_BD_READY; |
|
tx_last = (tx_last + 1) & ETH_TXBD_NUM_MASK; |
tx_full = 0; |
} |
|
/* Waits for packet and pass it to the upper layers */ |
unsigned long eth_rx (void) |
{ |
eth_bd *bd; |
unsigned long len = 0; |
|
bd = (eth_bd *)ETH_BD_BASE + ETH_TXBD_NUM; |
|
while(1) { |
|
int bad = 0; |
|
if(bd[rx_next].status & ETH_RX_BD_EMPTY) |
return len; |
|
if(bd[rx_next].status & ETH_RX_BD_OVERRUN) { |
printf("eth rx: ETH_RX_BD_OVERRUN\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_INVSIMB) { |
printf("eth rx: ETH_RX_BD_INVSIMB\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_DRIBBLE) { |
printf("eth rx: ETH_RX_BD_DRIBBLE\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_TOOLONG) { |
printf("eth rx: ETH_RX_BD_TOOLONG\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_SHORT) { |
printf("eth rx: ETH_RX_BD_SHORT\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_CRCERR) { |
printf("eth rx: ETH_RX_BD_CRCERR\n"); |
bad = 1; |
} |
if(bd[rx_next].status & ETH_RX_BD_LATECOL) { |
printf("eth rx: ETH_RX_BD_LATECOL\n"); |
bad = 1; |
} |
|
if(!bad) { |
receive((void *)bd[rx_next].addr, bd[rx_next].len); |
len += bd[rx_next].len; |
} |
|
bd[rx_next].status &= ~ETH_RX_BD_STATS; |
bd[rx_next].status |= ETH_RX_BD_EMPTY; |
|
rx_next = (rx_next + 1) & ETH_RXBD_NUM_MASK; |
} |
} |
|
void eth_int_enable(void) |
{ |
REG32(ETH_REG_BASE + ETH_INT_MASK) = ETH_INT_MASK_TXB | |
ETH_INT_MASK_TXE | |
ETH_INT_MASK_RXF | |
ETH_INT_MASK_RXE | |
ETH_INT_MASK_BUSY | |
ETH_INT_MASK_TXC | |
ETH_INT_MASK_RXC; |
} |
|
void eth_halt(void) |
{ |
/* Enable receiver and transmiter */ |
REG32(ETH_REG_BASE + ETH_MODER) &= ~(ETH_MODER_RXEN | ETH_MODER_TXEN); |
} |
|
void eth_int(void) |
{ |
} |
/drivers/tick.c
0,0 → 1,20
|
#include "common.h" |
#include "support.h" |
#include "spr_defs.h" |
|
#define TICKS_PER_SEC 100 |
|
void tick_init(void) |
{ |
mtspr(SPR_SR, SPR_SR_TEE | mfspr(SPR_SR)); |
mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | ((TICKS_PER_SEC/IN_CLK) & SPR_TTMR_PERIOD)); |
} |
|
void tick_interrupt(void) |
{ |
timestamp++; |
mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | ((TICKS_PER_SEC/IN_CLK) & SPR_TTMR_PERIOD)); |
} |
|
|
/drivers/uart.c
0,0 → 1,77
#include "support.h" |
#include "board.h" |
#include "uart.h" |
|
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) |
|
#define WAIT_FOR_XMITR \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) |
|
#define WAIT_FOR_THRE \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & UART_LSR_THRE) != UART_LSR_THRE) |
|
#define CHECK_FOR_CHAR (REG8(UART_BASE + UART_LSR) & UART_LSR_DR) |
|
#define WAIT_FOR_CHAR \ |
do { \ |
lsr = REG8(UART_BASE + UART_LSR); \ |
} while ((lsr & UART_LSR_DR) != UART_LSR_DR) |
|
#define UART_TX_BUFF_LEN 32 |
#define UART_TX_BUFF_MASK (UART_TX_BUFF_LEN -1) |
|
char tx_buff[UART_TX_BUFF_LEN]; |
volatile int tx_level, rx_level; |
|
void uart_init(void) |
{ |
int divisor; |
|
/* Reset receiver and transmiter */ |
REG8(UART_BASE + UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_14; |
|
/* Disable all interrupts */ |
REG8(UART_BASE + UART_IER) = 0x00; |
|
/* Set 8 bit char, 1 stop bit, no parity */ |
REG8(UART_BASE + UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP | UART_LCR_PARITY); |
|
/* Set baud rate */ |
divisor = IN_CLK/(16 * UART_BAUD_RATE); |
REG8(UART_BASE + UART_LCR) |= UART_LCR_DLAB; |
REG8(UART_BASE + UART_DLL) = divisor & 0x000000ff; |
REG8(UART_BASE + UART_DLM) = (divisor >> 8) & 0x000000ff; |
REG8(UART_BASE + UART_LCR) &= ~(UART_LCR_DLAB); |
} |
|
void uart_putc(char c) |
{ |
unsigned char lsr; |
|
WAIT_FOR_THRE; |
REG8(UART_BASE + UART_TX) = c; |
if(c == '\n') { |
WAIT_FOR_THRE; |
REG8(UART_BASE + UART_TX) = '\r'; |
} |
WAIT_FOR_XMITR; |
} |
|
char uart_getc(void) |
{ |
unsigned char lsr; |
char c; |
|
WAIT_FOR_CHAR; |
c = REG8(UART_BASE + UART_RX); |
return c; |
} |
|
char uart_testc(void) |
{ |
return ((REG8(UART_BASE + UART_LSR) & UART_LSR_DR) == UART_LSR_DR); |
} |
drivers/uart.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: drivers/Makefile
===================================================================
--- drivers/Makefile (nonexistent)
+++ drivers/Makefile (revision 1765)
@@ -0,0 +1,12 @@
+
+LIB = drivers.o
+OBJS = eth.o uart.o tick.o
+
+all: $(LIB)
+
+$(LIB): $(OBJS)
+ $(LD) -r -o $@ $(OBJS)
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+sinclude .depend