Cisco c2610 support.
parent
1e53ccbe5c
commit
8af0261a51
@ -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…
Reference in New Issue