Cisco c2610 support.

c2600
Jochen Friedrich 14 years ago
parent 1e53ccbe5c
commit 8af0261a51

@ -7,7 +7,8 @@ ifndef CROSS_COMPILE
CROSS_COMPILE=mips-elf-
endif
CFLAGS=-mno-abicalls
LDFLAGS=-Ttext ${TEXTADDR}
LDFLAGS=-Ttext=${TEXTADDR}
LINKSCRIPT=mips.lds
# Configuration for the Cisco 3660 Routers
# TARGET=c3600
@ -18,7 +19,8 @@ LDFLAGS=-Ttext ${TEXTADDR}
# CROSS_COMPILE=mips-elf-
# endif
# CFLAGS=-mno-abicalls
# LDFLAGS=-Ttext ${TEXTADDR}
# LDFLAGS=-Ttext=${TEXTADDR}
# LINKSCRIPT=mips.lds
# Configuration for the Cisco 1700 Series Routers
# TARGET=c1700
@ -29,6 +31,18 @@ LDFLAGS=-Ttext ${TEXTADDR}
# CROSS_COMPILE=powerpc-elf-
# endif
# LDFLAGS=-Ttext=${TEXTADDR}
# LINKSCRIPT=powerpc.lds
# Configuration for the Cisco 2600 Series Routers
# TARGET=c2600
# MACHCODE=0x2b
# TEXTADDR=0x80008000
# LOADADDR=0x80028000
# ifndef CROSS_COMPILE
# CROSS_COMPILE=powerpc-elf-
# endif
# LDFLAGS=-Ttext=${TEXTADDR}
# LINKSCRIPT=powerpc.lds
# Configuration for the Cisco 7200 Series Routers
# TARGET=c7200
@ -39,7 +53,8 @@ LDFLAGS=-Ttext ${TEXTADDR}
# CROSS_COMPILE=mips-elf-
# endif
# CFLAGS=-DDEBUG -mno-abicalls
# LDFLAGS=-Ttext ${TEXTADDR}
# LDFLAGS=-Ttext=${TEXTADDR}
# LINKSCRIPT=mips.lds
# additional CFLAGS
CFLAGS+=
@ -67,7 +82,7 @@ CFLAGS+=-fno-builtin -fomit-frame-pointer -fno-pic \
ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp
LDFLAGS+=--omagic -nostartfiles -nostdlib --discard-all --strip-all \
--entry _start
--entry _start -Wl,-T -Wl,${LINKSCRIPT}
OBJECTS=string.o main.o ciloio.o printf.o elf_loader.o lzma_loader.o \
LzmaDecode.o

@ -0,0 +1,16 @@
#ifndef _INCLUDE_MACH_C2600_PLATFORM_H
#define _INCLUDE_MACH_C2600_PLATFORM_H
#include <types.h>
#define FLASH_BASE 0x60000000
#define MEMORY_BASE 0x80000000
void platform_init();
uint32_t check_flash();
void flash_directory();
uint32_t locate_stage_two();
void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size,
uint32_t kern_loadpt);
#endif /* _INCLUDE_MACH_C2600_PLATFORM_H */

@ -0,0 +1,24 @@
#ifndef _INCLUDE_MACH_C2600_PLATIO
#define _INCLUDE_MACH_C2600_PLATIO
#include <types.h>
#include <ciloio.h>
/* a flash filesystem entry for the C2600 */
struct fs_ent {
uint32_t magic;
uint32_t length;
/* todo: figure out exactly what these two fields contain */
uint32_t crc32;
uint32_t date;
char filename[48];
};
void platio_file_open(struct file *fp, const char *filename);
uint32_t platio_read(void *pbuf, uint32_t size, uint32_t nmemb,
struct file *fp);
uint8_t platio_find_file(const char *filename);
#define FS_FILE_MAGIC 0xbad00b1e
#endif /* _INCLUDE_MACH_C2600_PLATIO */

@ -0,0 +1,18 @@
ifndef CROSS_COMPILE
CROSS_COMPILE=powerpc-elf-
endif
OBJECTS=start.o promlib.o platform.o platio.o
INCLUDE=-I../../include
all: ${OBJECTS}
.c.o:
$(CC) ${CFLAGS} ${INCLUDE} -c $<
.S.o:
$(CC) ${CFLAGS} ${INCLUDE} ${ASFLAGS} -c $<
clean:
-rm -f *.o

@ -0,0 +1,75 @@
/* Platform-specific operations for the Cisco 2600 Series router
* (c) 2009 Philippe Vachon <philippe@cowpig.ca>
*
* Licensed under the GNU General Public License v.2.0. See the COPYING
* file in the root directory of this source distribution for more info.
*/
#include <types.h>
#include <mach/c2600/platform.h>
#include <mach/c2600/platio.h>
#include <printf.h>
/**
* perform hardware-specifc initialization for this platform
*/
void platform_init()
{
}
/**
* Perform a sanity check on flash
* @returns 0 if no flash found, number of flash devices found otherwise
*/
uint32_t check_flash()
{
uint32_t *ptr = (uint32_t *)FLASH_BASE;
if (*ptr != FS_FILE_MAGIC) {
return 0;
}
return 1;
/* TODO: add support for PCMCIA flash */
}
/**
* print a directory listing of the 'main' flash device in the system
*/
void flash_directory()
{
struct fs_ent *f = (struct fs_ent *)FLASH_BASE;
uint32_t offset = 0;
/* Iterate over the files; f->magic is 0 if an invalid file is found. */
while (f->magic == FS_FILE_MAGIC) {
printf("%s\n", f->filename);
offset += sizeof(struct fs_ent) + f->length;
f = (struct fs_ent *)(FLASH_BASE + offset);
}
}
/**
* Locate the stage two loader for CiscoLoad for this particular platform
* returns 0 if not found, 1 if found
*/
uint32_t locate_stage_two()
{
return platio_find_file("ciscoload.two");
}
/**
* Kick into the stage two loader.
*/
void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size,
uint32_t kern_loadpt)
{
uint32_t s2addr = ((uint32_t)find_file("ciscoload.two", FLASH_BASE)) +
sizeof(struct fs_ent);
((void (*)(uint32_t data_offset, uint32_t data_length, uint32_t entry_pt,
uint32_t load_offset)) (s2addr))
(kern_off, kern_size, kern_entry, kern_loadpt);
}

@ -0,0 +1,98 @@
/* Platform specific operations for I/O for the cisco 2600 Series
* (C) 2008 Philippe Vachon <philippe@cowpig.ca>
*
* Licensed under the GNU General Public License v2.
*/
#include <types.h>
#include <mach/c2600/platio.h>
#include <ciloio.h>
#include <string.h>
#include <mach/c2600/platform.h>
/* find file in filesystem starting at base */
struct fs_ent *find_file(const char *filename, uint32_t base)
{
/* Actual file offset */
uint32_t offset = 0;
struct fs_ent *f = (struct fs_ent *)(base + offset);
/* iterate over files in flash */
while (f->magic == FS_FILE_MAGIC) {
if (!strncmp(f->filename, filename, 48)) {
return f;
}
offset += sizeof(struct fs_ent) + f->length;
f = (struct fs_ent *)(base + offset);
}
return NULL;
}
/**
* Find a file within the platform-supported I/O devices
* @param filename the file
* @returns 0 on failure, device ID number on success
*/
uint8_t platio_find_file(const char *filename)
{
if (find_file(filename, FLASH_BASE)) {
return 1;
}
/* todo: add support for PCMCIA devices */
return 0;
}
/**
* Open a file.
* @param fp File structure to hold file information
* @param filename name of the file
*/
void platio_file_open(struct file *fp, const char *filename)
{
struct fs_ent *ent = find_file(filename, FLASH_BASE);
if (ent == NULL) {
fp->code = 0;
fp->private = NULL;
return;
}
fp->dev = 1; /* TODO: add support for PCMCIA flash */
fp->private = (void *)ent;
fp->file_len = ent->length;
fp->file_pos = 0;
/* copy the filename */
strncpy(fp->filename, ent->filename, 48);
fp->code = 1;
}
/**
* Read data from a given file
* @param pbuf Buffer to read data into
* @param size size of entity to be read
* @param nmemb number of members to read
* @param fp file information structure to read from.
* @returns number of bytes read (should = size * nmemb for C3600)
*/
uint32_t platio_read(void *pbuf, uint32_t size, uint32_t nmemb, struct file *fp)
{
/* calculate the effective offset of the data we want to read: */
char *from = (char *)((uint32_t)(fp->private) + sizeof(struct fs_ent) +
fp->file_pos);
memcpy(pbuf, from, size * nmemb);
fp->file_pos += size * nmemb;
return nmemb * size;
}

@ -0,0 +1,163 @@
/**
* low-level prom and I/O library for the Cisco 2600 series
* (C) 2008 Philippe Vachon <philippe@cowpig.ca>
* -----------------------------------------------------------
* Licensed under the GNU General Public License v2.0. See
* COPYING in the root directory of the source distribution for details.
*/
#include <promlib.h>
#include <types.h>
#include <asm/ppc_asm.h>
#define UART_BASE 0xffe00000
#define UART_LSR 0x5
/* putc
* output character c to console
* @param c ASCII number for character
*/
void c_putc(const char c)
{
while (!(*((char *)(UART_BASE + UART_LSR)) & 0x20));
((char *)UART_BASE)[0] = c;
}
/* puts - wrapper for putc
* output the string pointed to by s
* @param s String to be written to the console
*/
void c_puts(const char *s)
{
while(*s != '\0') {
c_putc(*(s++));
if (*s == '\n') {
c_putc('\r');
}
}
}
/* putsn - put a string of length n on the console
* @param s string to be written
* @param n length
*/
void c_putsn(const char *s, int n)
{
int i = 0;
while (*s != '\0' && i != n) {
c_putc(*(s++));
i++;
}
}
/* getc - Syscall n
* get one character of input from the console
* @return ASCII code for character read from console
*/
char c_getc(void)
{
char c;
while (!(*((uint8_t *)(UART_BASE + UART_LSR)) & 0x01));
c = ((uint8_t *)UART_BASE)[0];
return c;
}
/* gets - wrapper for getc
* reads up to n characters into buffer b
* @param b Buffer to read characters into
* @param n size of buffer
* @return the number of characters read into b
*/
int c_gets(char *b, int n)
{
int i = 0;
do {
b[i] = c_getc();
c_putc(b[i]);
i++;
if (b[i - 1] == '\n' || b[i-1] == '\r') {
break;
}
else if (b[i - 1] == 0x8 || b[i - 1] == 0x7f) {
i-=2;
}
} while (i < n);
b[i - 1] = '\0';
return i;
}
/* c_version - get version string
* @return pointer to version string
*/
char *c_verstr(void)
{
return "Cisco 2600 Series Router";
}
/* memsz - get total memory size (in bytes)
* @return the size of the memory installed in the router, in bytes
*/
int c_memsz(void)
{
int m = 0;
__asm__ (
"li 3, 4\n"
"sc\n"
"mr %[memsz], 3\n"
: [memsz]"=r"(m)
: /* no inputs */
: "r3","memory","cc"
);
return m;
}
/* timer - get number of ticks from timer
* @return the value in the timer
*/
long c_timer(void)
{
return 0;
}
/* String length with a maximum length allowed
* @param s pointer to string
* @param maxlen maximum length
*/
int c_strnlen(const char *s, int maxlen)
{
int i = 0;
if (!s) return 0;
while (*(s++) != '\0' && i != maxlen) {
i++;
}
return i;
}
/* baud - get console baud rate
* @return boot console baud rate
*/
int c_baud(void)
{
int b = 115200;
__asm__ (
"li 3, 62\n"
"sc\n"
"mr %[baud], 3\n"
: [baud]"=r"(b)
: /* no returns */
: "r3", "memory", "cc"
);
return b;
}

@ -0,0 +1,29 @@
/* CILO entry point for the Cisco 2600 Series Routers
* (C) 2009 Philippe Vachon <philippe@cowpig.ca>
* Licensed under the GNU General Public License v2.0 or later. See
* COPYING in the root of the source distribution for more details.
*/
#include <asm/ppc_asm.h>
.text
.globl _start
_start:
/* put a letter C to show we are alive */
lis r26, 0xffe0
putchar:
lbz r0, 5(r26)
andi. r0, r0, 0x20
beq putchar
/* put the C */
li r3, 67
stb r3, 0(r26)
/* jump to the C code */
bl start_bootloader
.end _start
.size _start, .-_start

@ -0,0 +1,28 @@
OUTPUT_ARCH(mips)
ENTRY(_start)
EXTERN(_start)
SECTIONS
{
.text :
{
. = ALIGN(4096);
*(.reginfo)
*(.text)
*(.rodata*)
*(.data*)
*(.sdata*)
*(.got2)
*(.bss)
*(.sbss)
*(.pdr)
}
/DISCARD/ :
{
*(.comment)
*(.note.GNU-stack)
*(.gnu.attributes)
}
}

@ -0,0 +1,30 @@
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
EXTERN(_start)
PHDRS
{
text PT_LOAD FILEHDR PHDRS ;
}
SECTIONS
{
.text :
{
. = ALIGN(4096);
*(.text)
*(.rodata*)
*(.data*)
*(.sdata*)
*(.got2)
*(.bss)
*(.sbss)
} :text
/DISCARD/ :
{
*(.comment)
*(.note.GNU-stack)
*(.gnu.attributes)
}
}
Loading…
Cancel
Save