Added C7200 support (thanks to V�g� Tibor).

master
Philippe Vachon 16 years ago
parent b5ecd94191
commit 1e53ccbe5c

3
.gitignore vendored

@ -0,0 +1,3 @@
*.o
*.elf
*.bin

@ -30,6 +30,17 @@ LDFLAGS=-Ttext ${TEXTADDR}
# endif # endif
# LDFLAGS=-Ttext=${TEXTADDR} # LDFLAGS=-Ttext=${TEXTADDR}
# Configuration for the Cisco 7200 Series Routers
# TARGET=c7200
# MACHCODE=0x19
# TEXTADDR=0x80008000
# LOADADDR=0x80028000
# ifndef CROSS_COMPILE
# CROSS_COMPILE=mips-elf-
# endif
# CFLAGS=-DDEBUG -mno-abicalls
# LDFLAGS=-Ttext ${TEXTADDR}
# additional CFLAGS # additional CFLAGS
CFLAGS+= CFLAGS+=

@ -0,0 +1,15 @@
#ifndef _INCLUDE_MACH_C7200_PLATFORM_H
#define _INCLUDE_MACH_C7200_PLATFORM_H
#include <types.h>
#define FLASH_BASE 0xBA000000
#define FLASHFS_BASE 0xBA040000
#define KERNEL_ENTRY_POINT 0x80008000
#define MEMORY_BASE 0x80000000
void platform_init();
uint32_t check_flash();
void flash_directory();
#endif /* _INCLUDE_MACH_C7200_PLATFORM_H */

@ -0,0 +1,37 @@
#ifndef _INCLUDE_MACH_C7200_PLATIO
#define _INCLUDE_MACH_C7200_PLATIO
#include <types.h>
#include <ciloio.h>
/* a flash filesystem entry for the C7200 */
struct fs_ent {
uint32_t magic; /* C7200 bootflash filesystem magi number */
uint32_t fileno; /* number of the file */
char filename[64]; /* 64bytes filename string*/
uint32_t length; /* size of the file in bytes */
uint32_t seek; /* address of the next fs_ent from FLASH_BASE (0xBA000000) and not FLASHFS_BASE (0xBA040000) */
uint32_t crc32; /* CRC32 value of the file */
uint32_t type; /* file type (ascii or binary etc.) */
uint32_t date; /* the file last modification time in UNIX time */
/* todo: figure out exactly what these two fields contain */
uint32_t sg01; /* 0xffffffffh */
uint32_t sg02; /* 0xfffffff8h */
uint32_t sg03; /* 0xffffffffh */
uint32_t sg04; /* 0xffffffffh */
uint32_t sg05; /* 0xffffffffh */
uint32_t sg06; /* 0xffffffffh */
uint32_t sg07; /* 0xffffffffh */
uint32_t sg08; /* 0xffffffffh */
uint32_t sg09; /* 0xffffffffh */
};
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 0x07158805
#endif /* _INCLUDE_MACH_C7200_PLATIO */

@ -0,0 +1,18 @@
ifndef CROSS_COMPILE
CROSS_COMPILE=mips-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,44 @@
#include <types.h>
#include <mach/c7200/platform.h>
#include <mach/c7200/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 *)FLASHFS_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 *)FLASHFS_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 *)(FLASHFS_BASE + offset);
}
}

@ -0,0 +1,97 @@
/* Platform specific operations for I/O for the cisco 7200 Series
* (C) 2008 Philippe Vachon <philippe@cowpig.ca>
*
* Licensed under the GNU General Public License v2.
*/
#include <types.h>
#include <mach/c7200/platio.h>
#include <ciloio.h>
#include <string.h>
#include <mach/c7200/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, 64)) {
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, FLASHFS_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, FLASHFS_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, 64);
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 C7200)
*/
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,206 @@
/**
* PROM Library for Cisco Systems 7200 Series Routers
* (C) 2008 Philippe Vachon <philippe@cowpig.ca>
* -----------------------------------------------------------
*/
/**
* Calling convention:
* a0 - syscall number
* a1 - arg1 ... etc
* v0 - returned value from syscall
*/
#include <promlib.h>
/* putc - Syscall 1
* output character c to console
* @param c ASCII number for character
*/
void c_putc(const char c)
{
asm ( ".set noreorder\n "
"li $a0, %[syscall]\n"
"lb $a1, (%[character])\n"
"syscall\n"
"nop\n"
".set reorder\n"
: /* no output */
: [character] "r"(&c), [syscall] "g"(PUTC)
: "a0", "a1"
);
}
/* 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++));
}
}
/* 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;
asm ( ".set noreorder\n "
"li $a0, %[syscall]\n"
"syscall\n"
"nop\n"
"move %[charout], $v0 \n"
".set reorder\n"
: [charout] "=r" (c)
: [syscall] "g" (GETC)
: "a0","v0"
);
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) {
i--;
}
} while (i < n);
b[i - 1] = '\0';
return i;
}
/* c_version - get version string
* @return pointer to version string
*/
char *c_verstr(void)
{
char *c;
asm ( ".set noreorder\n"
"li $a0, %[syscall]\n"
"syscall\n"
"nop\n"
"move %[result], $v0\n"
".set reorder\n"
: [result] "=r" (c)
: [syscall] "g" (VERSION)
: "a0", "v0"
);
return c;
}
/* memsz - get total memory size (in bytes)
* @return the size of the memory installed in the router, in bytes
*/
int c_memsz(void)
{
int r = 0;
asm ( " .set noreorder \n"
"li $a0, %[syscall]\n"
"syscall\n"
"nop\n"
"move %[result], $v0\n"
".set reorder\n"
: [result] "=r" (r)
: [syscall] "g" (MEMSIZE)
: "a0","v0"
);
return r;
}
/* timer - get number of ticks from timer
* @return the value in the timer
*/
long c_timer(void)
{
long t = 0;
asm (" .set noreorder\n"
"li $a0, %[syscall]\n"
"syscall\n"
"nop\n"
"move %[result], $a0\n"
".set reorder\n"
: [result]"=r"(t)
: [syscall]"g"(TIMER)
: "a0","v0"
);
return t;
}
/* 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 = 0;
asm volatile (".set noreorder\n"
"li $a0, %[syscall]\n"
"syscall\n"
"nop\n"
"move %[result], $a0\n"
".set reorder\n"
: [result]"=r"(b)
: [syscall]"g"(GETBAUD)
: "a0", "v0"
);
return b;
}

@ -0,0 +1,52 @@
/* Initial entry point for ciscoboot. Sets up some stack at 0x80008000
* and jumps to main
*/
#include <asm/regdef.h>
#include <asm/asm.h>
EXPORT(_start)
.extern start_bootloader
LEAF(_start)
.set noreorder
li sp, 0x80008000
/* Save return address */
sw ra, -4(sp)
/* print out a letter C */
li a0, 1
li a1, 67
syscall
nop
/* get the total amount of RAM */
li a0, 4
syscall
nop
/* set the stack at the top of RAM */
li sp, 0x80000000
add sp, sp, v0
/* save return address*/
/*sw ra, -4(sp)
addi sp, sp, -4 */
/* start bootloader */
jal start_bootloader
nop
/* bootloader failed for some reason: */
li sp, 0x80008000
/* re-load return address to ROM: */
ld ra, -4(sp)
jr ra
.set reorder
END(_start)
Loading…
Cancel
Save