start.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
- /*
- * BK Id: SCCS/s.start.c 1.20 04/09/02 21:01:58 paulus
- */
- /*
- * Copyright (C) 1996 Paul Mackerras.
- */
- #include <linux/config.h>
- #include <linux/string.h>
- #include <asm/machdep.h>
- #include <asm/io.h>
- #include <asm/page.h>
- #include <linux/adb.h>
- #include <linux/pmu.h>
- #include <linux/cuda.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <asm/prom.h>
- #include <asm/bootx.h>
- #include <asm/machdep.h>
- #include <asm/pmac_feature.h>
- #include <asm/processor.h>
- #include <asm/delay.h>
- #include <asm/btext.h>
- #ifdef CONFIG_SMP
- #include <asm/bitops.h>
- #endif
- static volatile unsigned char *sccc, *sccd;
- unsigned long TXRDY, RXRDY;
- extern void xmon_printf(const char *fmt, ...);
- static int xmon_expect(const char *str, unsigned int timeout);
- static int console;
- static int use_screen;
- static int via_modem;
- static int xmon_use_sccb;
- static struct device_node *channel_node;
- #define TB_SPEED 25000000
- static inline unsigned int readtb(void)
- {
- unsigned int ret;
- asm volatile("mftb %0" : "=r" (ret) :);
- return ret;
- }
- void buf_access(void)
- {
- if ( _machine == _MACH_chrp )
- sccd[3] &= ~0x80; /* reset DLAB */
- }
- extern int adb_init(void);
- void
- xmon_map_scc(void)
- {
- #ifdef CONFIG_ALL_PPC
- volatile unsigned char *base;
- use_screen = 0;
-
- if (_machine == _MACH_Pmac) {
- struct device_node *np;
- unsigned long addr;
- #ifdef CONFIG_BOOTX_TEXT
- if (!machine_is_compatible("iMac")) {
- /* see if there is a keyboard in the device tree
- with a parent of type "adb" */
- for (np = find_devices("keyboard"); np; np = np->next)
- if (np->parent && np->parent->type
- && strcmp(np->parent->type, "adb") == 0)
- break;
- /* needs to be hacked if xmon_printk is to be used
- from within find_via_pmu() */
- #ifdef CONFIG_ADB_PMU
- if (np != NULL && boot_text_mapped && find_via_pmu())
- use_screen = 1;
- #endif
- #ifdef CONFIG_ADB_CUDA
- if (np != NULL && boot_text_mapped && find_via_cuda())
- use_screen = 1;
- #endif
- }
- if (!use_screen && (np = find_devices("escc")) != NULL) {
- /*
- * look for the device node for the serial port
- * we're using and see if it says it has a modem
- */
- char *name = xmon_use_sccb? "ch-b": "ch-a";
- char *slots;
- int l;
- np = np->child;
- while (np != NULL && strcmp(np->name, name) != 0)
- np = np->sibling;
- if (np != NULL) {
- /* XXX should parse this properly */
- channel_node = np;
- slots = get_property(np, "slot-names", &l);
- if (slots != NULL && l >= 10
- && strcmp(slots+4, "Modem") == 0)
- via_modem = 1;
- }
- }
- btext_drawstring("xmon uses ");
- if (use_screen)
- btext_drawstring("screen and keyboardn");
- else {
- if (via_modem)
- btext_drawstring("modem on ");
- btext_drawstring(xmon_use_sccb? "printer": "modem");
- btext_drawstring(" portn");
- }
- #endif /* CONFIG_BOOTX_TEXT */
- #ifdef CHRP_ESCC
- addr = 0xc1013020;
- #else
- addr = 0xf3013020;
- #endif
- TXRDY = 4;
- RXRDY = 1;
-
- np = find_devices("mac-io");
- if (np && np->n_addrs)
- addr = np->addrs[0].address + 0x13020;
- base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
- sccc = base + (addr & ~PAGE_MASK);
- sccd = sccc + 0x10;
- }
- else
- {
- /* should already be mapped by the kernel boot */
- sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
- sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
- if (xmon_use_sccb) {
- sccc -= 0x100;
- sccd -= 0x100;
- }
- TXRDY = 0x20;
- RXRDY = 1;
- }
- #elif defined(CONFIG_GEMINI)
- /* should already be mapped by the kernel boot */
- sccc = (volatile unsigned char *) 0xffeffb0d;
- sccd = (volatile unsigned char *) 0xffeffb08;
- TXRDY = 0x20;
- RXRDY = 1;
- console = 1;
- #endif /* platform */
- }
- static int scc_initialized = 0;
- void xmon_init_scc(void);
- extern void pmu_poll(void);
- extern void cuda_poll(void);
- static inline void do_poll_adb(void)
- {
- #ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
- #endif /* CONFIG_ADB_PMU */
- #ifdef CONFIG_ADB_CUDA
- if (sys_ctrler == SYS_CTRLER_CUDA)
- cuda_poll();
- #endif /* CONFIG_ADB_CUDA */
- }
- int
- xmon_write(void *handle, void *ptr, int nb)
- {
- char *p = ptr;
- int i, c, ct;
- #ifdef CONFIG_SMP
- static unsigned long xmon_write_lock;
- int lock_wait = 1000000;
- int locked;
- while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
- if (--lock_wait == 0)
- break;
- #endif
- #ifdef CONFIG_BOOTX_TEXT
- if (use_screen) {
- /* write it on the screen */
- for (i = 0; i < nb; ++i)
- btext_drawchar(*p++);
- goto out;
- }
- #endif
- if (!scc_initialized)
- xmon_init_scc();
- ct = 0;
- for (i = 0; i < nb; ++i) {
- while ((*sccc & TXRDY) == 0)
- do_poll_adb();
- c = p[i];
- if (c == 'n' && !ct) {
- c = 'r';
- ct = 1;
- --i;
- } else {
- if (console)
- printk("%c", c);
- ct = 0;
- }
- buf_access();
- *sccd = c;
- eieio();
- }
- out:
- #ifdef CONFIG_SMP
- if (!locked)
- clear_bit(0, &xmon_write_lock);
- #endif
- return nb;
- }
- int xmon_wants_key;
- int xmon_adb_keycode;
- #ifdef CONFIG_BOOTX_TEXT
- static int xmon_adb_shiftstate;
- static unsigned char xmon_keytab[128] =
- "asdfhgzxcv 00bqwer" /* 0x00 - 0x0f */
- "yt123465=97-80]o" /* 0x10 - 0x1f */
- "u[iprlj'k;\,/nm." /* 0x20 - 0x2f */
- "t `177 33 " /* 0x30 - 0x3f */
- "