From 8c72b797b421258e17ad6f7afcbc2ab9105e8dc8 Mon Sep 17 00:00:00 2001 From: ejka Date: Sun, 18 Mar 2007 09:40:51 +0000 Subject: Add ar7-2.6 port (marked as broken for now). git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6600 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/ar7-2.6/files/arch/mips/ar7/prom.c | 266 ++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 target/linux/ar7-2.6/files/arch/mips/ar7/prom.c (limited to 'target/linux/ar7-2.6/files/arch/mips/ar7/prom.c') diff --git a/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c b/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c new file mode 100644 index 000000000..4db430382 --- /dev/null +++ b/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c @@ -0,0 +1,266 @@ +/* + * $Id$ + * + * Copyright (C) 2006, 2007 OpenWrt.org + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * Putting things on the screen/serial line using YAMONs facilities. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_ENTRY 80 + +struct env_var { + char *name; + char *value; +}; + +struct psp_chip_map { + u16 chip; + char *names[50]; +}; + +/* I hate this. No. *I* *HATE* *THIS* */ +static __initdata struct psp_chip_map psp_chip_map[] = { + { + .chip = 0x5, + .names = { + "dummy", "cpufrequency", "memsize", + "flashsize", "modetty0", "modetty1", "prompt", + "bootcfg", "maca", "macb", "usb_rndis_mac", + "macap", "my_ipaddress", "server_ipaddress", + "bline_maca", "bline_macb", "bline_rndis", + "bline_atm", "usb_pid", "usb_vid", + "usb_eppolli", "gateway_ipaddress", + "subnet_mask", "usb_serial", "usb_board_mac", + "remote_user", "remote_pass", "remote_dir", + "sysfrequency", "link_timeout", "mac_port", + "path", "hostname", "tftpcfg", "buildops", + "tftp_fo_fname", "tftp_fo_ports", + "console_state", "mipsfrequency", + }, + }, + { + .chip = 0x18, + .names = { + "dummy", "cpufrequency", "memsize", + "flashsize", "modetty0", "modetty1", "prompt", + "bootcfg", "maca", "macb", "usb_rndis_mac", + "macap", "my_ipaddress", "server_ipaddress", + "bline_maca", "bline_macb", "bline_rndis", + "bline_atm", "usb_pid", "usb_vid", + "usb_eppolli", "gateway_ipaddress", + "subnet_mask", "usb_serial", "usb_board_mac", + "remote_user", "remote_pass", "remote_dir", + "sysfrequency", "link_timeout", "mac_port", + "path", "hostname", "tftpcfg", "buildops", + "tftp_fo_fname", "tftp_fo_ports", + "console_state", "mipsfrequency", + }, + }, + { + .chip = 0x2b, + .names = { + "dummy", "cpufrequency", "memsize", + "flashsize", "modetty0", "modetty1", "prompt", + "bootcfg", "maca", "macb", "usb_rndis_mac", + "macap", "my_ipaddress", "server_ipaddress", + "bline_maca", "bline_macb", "bline_rndis", + "bline_atm", "usb_pid", "usb_vid", + "usb_eppolli", "gateway_ipaddress", + "subnet_mask", "usb_serial", "usb_board_mac", + "remote_user", "remote_pass", "remote_dir", + "sysfrequency", "link_timeout", "mac_port", + "path", "hostname", "tftpcfg", "buildops", + "tftp_fo_fname", "tftp_fo_ports", + "console_state", "mipsfrequency", + }, + }, + { + .chip = 0x0, + }, +}; + +static struct env_var adam2_env[MAX_ENTRY] = { { 0, }, }; + +char * __init prom_getenv(char *name) +{ + int i; + for (i = 0; (i < MAX_ENTRY) && adam2_env[i].name; i++) + if (!strcmp(name, adam2_env[i].name)) + return adam2_env[i].value; + + return NULL; +} + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +static void __init ar7_init_cmdline(int argc, char *argv[]) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < argc) { + strcpy(cp, argv[actr]); + cp += strlen(argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) { + /* get rid of trailing space */ + --cp; + *cp = '\0'; + } +} + +struct psbl_rec { + u32 psbl_size; + u32 env_base; + u32 env_size; + u32 ffs_base; + u32 ffs_size; +}; + +static __initdata char psp_env_version[] = "TIENV0.8"; + +struct psp_env_var { + unsigned char num; + unsigned char ctrl; + unsigned short csum; + unsigned char len; + unsigned char data[11]; +}; + +static char psp_env_data[2048] = { 0, }; + +static void __init add_adam2_var(char *name, char *value) +{ + int i; + for (i = 0; i < MAX_ENTRY; i++) { + if (!adam2_env[i].name) { + adam2_env[i].name = name; + adam2_env[i].value = value; + return; + } else if (!strcmp(adam2_env[i].name, name)) { + adam2_env[i].value = value; + return; + } + } +} + +static int __init parse_psp_env(void *start) +{ + int i, j; + u16 chip; + struct psp_chip_map *map; + char *src, *dest, *name, *value; + struct psp_env_var *vars = start; + + chip = get_chip_id(); + for (map = psp_chip_map; map->chip; map++) + if (map->chip == chip) + break; + + if (!map->chip) + return -EINVAL; + + i = 1; + j = 0; + dest = psp_env_data; + while (vars[i].num < 0xff) { + src = vars[i].data; + if (vars[i].num) { + strcpy(dest, map->names[vars[i].num]); + name = dest; + } else { + strcpy(dest, src); + name = dest; + src += strlen(src) + 1; + } + dest += strlen(dest) + 1; + strcpy(dest, src); + value = dest; + dest += strlen(dest) + 1; + add_adam2_var(name, value); + i += vars[i].len; + } + return 0; +} + +static void __init ar7_init_env(struct env_var *env) +{ + int i; + struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300)); + void *psp_env = (void *)KSEG1ADDR(psbl->env_base); + + if(strcmp(psp_env, psp_env_version) == 0) { + parse_psp_env(psp_env); + } else { + for (i = 0; i < MAX_ENTRY; i++, env++) + if (env->name) + add_adam2_var(env->name, env->value); + } +} + +void __init prom_init(void) +{ + prom_printf("\nLINUX running...\n"); + ar7_init_cmdline(fw_arg0, (char **)fw_arg1); + ar7_init_env((struct env_var *)fw_arg2); +} + +#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4))) +static inline unsigned int serial_in(int offset) +{ + return readb((void *)PORT(offset)); +} + +static inline void serial_out(int offset, int value) +{ + writeb(value, (void *)PORT(offset)); +} + +char prom_getchar(void) +{ + while (!(serial_in(UART_LSR) & UART_LSR_DR)); + return serial_in(UART_RX); +} + +int prom_putchar(char c) +{ + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0); + serial_out(UART_TX, c); + return 1; +} + +EXPORT_SYMBOL(prom_getenv); -- cgit v1.2.3