diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
commit | dcec8a13bf565e47942a1751a9cec21bec5648fe (patch) | |
tree | 548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/sparc/prom | |
parent | 2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff) |
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash.
o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/sparc/prom')
-rw-r--r-- | arch/sparc/prom/Makefile | 8 | ||||
-rw-r--r-- | arch/sparc/prom/bootstr.c | 8 | ||||
-rw-r--r-- | arch/sparc/prom/console.c | 26 | ||||
-rw-r--r-- | arch/sparc/prom/devmap.c | 13 | ||||
-rw-r--r-- | arch/sparc/prom/devops.c | 17 | ||||
-rw-r--r-- | arch/sparc/prom/init.c | 16 | ||||
-rw-r--r-- | arch/sparc/prom/memory.c | 22 | ||||
-rw-r--r-- | arch/sparc/prom/misc.c | 21 | ||||
-rw-r--r-- | arch/sparc/prom/mp.c | 21 | ||||
-rw-r--r-- | arch/sparc/prom/ranges.c | 4 | ||||
-rw-r--r-- | arch/sparc/prom/segment.c | 9 | ||||
-rw-r--r-- | arch/sparc/prom/sun4prom.c | 161 | ||||
-rw-r--r-- | arch/sparc/prom/tree.c | 30 |
13 files changed, 252 insertions, 104 deletions
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 9c820a006..917aa9ad7 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 1995/11/25 00:59:48 davem Exp $ +# $Id: Makefile,v 1.6 1998/01/30 10:58:59 jj Exp $ # Makefile for the Sun Boot PROM interface library under # Linux. # @@ -9,7 +9,11 @@ # Note 2! The CFLAGS definitions are now in the main makefile... OBJS = bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \ - palloc.o ranges.o segment.o tree.o console.o printf.o + palloc.o ranges.o segment.o console.o printf.o tree.o + +ifeq ($(CONFIG_SUN4),y) +OBJS += sun4prom.o +endif all: promlib.a diff --git a/arch/sparc/prom/bootstr.c b/arch/sparc/prom/bootstr.c index e7bd9b06d..10a603455 100644 --- a/arch/sparc/prom/bootstr.c +++ b/arch/sparc/prom/bootstr.c @@ -1,4 +1,4 @@ -/* $Id: bootstr.c,v 1.14 1997/06/19 16:28:49 jj Exp $ +/* $Id: bootstr.c,v 1.17 1998/02/09 13:26:21 jj Exp $ * bootstr.c: Boot string/argument acquisition from the PROM. * * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -7,12 +7,15 @@ #include <linux/config.h> #include <linux/string.h> #include <asm/oplib.h> +#include <asm/sun4prom.h> #include <linux/init.h> #define BARG_LEN 256 -static char barg_buf[BARG_LEN] __initdata = { 0 }; +static char barg_buf[BARG_LEN] = { 0 }; static char fetched __initdata = 0; +extern linux_sun4_romvec *sun4_romvec; + __initfunc(char * prom_getbootargs(void)) { @@ -26,6 +29,7 @@ prom_getbootargs(void)) switch(prom_vers) { case PROM_V0: + case PROM_SUN4: cp = barg_buf; /* Start from 1 and go over fd(0,0,0)kernel */ for(iter = 1; iter < 8; iter++) { diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c index 4c999477b..3bbc7ade0 100644 --- a/arch/sparc/prom/console.c +++ b/arch/sparc/prom/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.14 1997/05/14 20:44:58 davem Exp $ +/* $Id: console.c,v 1.17 1998/03/09 14:04:21 jj Exp $ * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * @@ -10,12 +10,12 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <asm/openprom.h> +#include <asm/sun4prom.h> #include <asm/oplib.h> #include <asm/system.h> #include <linux/string.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. @@ -30,6 +30,7 @@ prom_nbgetchar(void) save_flags(flags); cli(); switch(prom_vers) { case PROM_V0: + case PROM_SUN4: i = (*(romvec->pv_nbgetchar))(); break; case PROM_V2: @@ -45,9 +46,7 @@ prom_nbgetchar(void) i = -1; break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -65,6 +64,7 @@ prom_nbputchar(char c) save_flags(flags); cli(); switch(prom_vers) { case PROM_V0: + case PROM_SUN4: i = (*(romvec->pv_nbputchar))(c); break; case PROM_V2: @@ -89,9 +89,7 @@ prom_nbputchar(char c) i = -1; break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return i; /* Ugh, we could spin forever on unsupported proms ;( */ } @@ -125,6 +123,7 @@ prom_query_input_device() switch(prom_vers) { case PROM_V0: case PROM_V2: + case PROM_SUN4: default: switch(*romvec->pv_stdin) { case PROMDEV_KBD: return PROMDEV_IKBD; @@ -136,9 +135,7 @@ prom_query_input_device() case PROM_V3: save_flags(flags); cli(); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); if(prom_node_has_property(st_p, "keyboard")) return PROMDEV_IKBD; @@ -173,6 +170,7 @@ prom_query_output_device() switch(prom_vers) { case PROM_V0: + case PROM_SUN4: switch(*romvec->pv_stdin) { case PROMDEV_SCREEN: return PROMDEV_OSCREEN; case PROMDEV_TTYA: return PROMDEV_OTTYA; @@ -183,9 +181,7 @@ prom_query_output_device() case PROM_V3: save_flags(flags); cli(); st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb)); if (propl >= 0 && propl == sizeof("display") && diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c index cd99ac3d6..463b07527 100644 --- a/arch/sparc/prom/devmap.c +++ b/arch/sparc/prom/devmap.c @@ -1,4 +1,4 @@ -/* $Id: devmap.c,v 1.5 1997/05/14 20:44:59 davem Exp $ +/* $Id: devmap.c,v 1.6 1998/03/09 14:04:23 jj Exp $ * promdevmap.c: Map device/IO areas to virtual addresses. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -11,8 +11,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Just like the routines in palloc.c, these should not be used * by the kernel at all. Bootloader facility mainly. And again, @@ -35,9 +34,7 @@ prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes) else ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr, num_bytes); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return ret; } @@ -51,9 +48,7 @@ prom_unmapio(char *vaddr, unsigned int num_bytes) if(num_bytes == 0x0) return; save_flags(flags); cli(); (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return; } diff --git a/arch/sparc/prom/devops.c b/arch/sparc/prom/devops.c index f7feb0815..c273b9922 100644 --- a/arch/sparc/prom/devops.c +++ b/arch/sparc/prom/devops.c @@ -1,4 +1,4 @@ -/* $Id: devops.c,v 1.10 1997/05/14 20:44:59 davem Exp $ +/* $Id: devops.c,v 1.11 1998/03/09 14:04:24 jj Exp $ * devops.c: Device operations using the PROM. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -10,8 +10,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Open the device described by the string 'dstr'. Returns the handle * to that device used for subsequent operations on that device. @@ -37,9 +36,7 @@ prom_devopen(char *dstr) handle = -1; break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return handle; @@ -63,9 +60,7 @@ prom_devclose(int dhandle) default: break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return 0; } @@ -90,9 +85,7 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) default: break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return; diff --git a/arch/sparc/prom/init.c b/arch/sparc/prom/init.c index 6f691464a..2c70dd95a 100644 --- a/arch/sparc/prom/init.c +++ b/arch/sparc/prom/init.c @@ -1,8 +1,9 @@ -/* $Id: init.c,v 1.11 1997/03/18 17:58:24 jj Exp $ +/* $Id: init.c,v 1.12 1998/01/30 10:59:02 jj Exp $ * init.c: Initialize internal variables used by the PROM * library functions. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ #include <linux/config.h> @@ -11,10 +12,12 @@ #include <asm/openprom.h> #include <asm/oplib.h> +#include <asm/sun4prom.h> struct linux_romvec *romvec; enum prom_major_version prom_vers; unsigned int prom_rev, prom_prev; +linux_sun4_romvec *sun4_romvec; /* The root node of the prom device tree. */ int prom_root_node; @@ -34,11 +37,14 @@ extern void prom_ranges_init(void); __initfunc(void prom_init(struct linux_romvec *rp)) { +#ifdef CONFIG_SUN4 + extern struct linux_romvec *sun4_prom_init(void); + rp = sun4_prom_init(); +#endif #if CONFIG_AP1000 extern struct linux_romvec *ap_prom_init(void); rp = ap_prom_init(); #endif - romvec = rp; switch(romvec->pv_romvers) { @@ -51,6 +57,9 @@ __initfunc(void prom_init(struct linux_romvec *rp)) case 3: prom_vers = PROM_V3; break; + case 40: + prom_vers = PROM_SUN4; + break; case 42: /* why not :-) */ prom_vers = PROM_AP1000; break; @@ -83,8 +92,11 @@ __initfunc(void prom_init(struct linux_romvec *rp)) prom_ranges_init(); +#ifndef CONFIG_SUN4 + /* SUN4 prints this in sun4_prom_init */ printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n", romvec->pv_romvers, prom_rev); +#endif /* Initialization successful. */ return; diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index b53bd17ea..af5019eb8 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -1,8 +1,9 @@ -/* $Id: memory.c,v 1.12 1997/05/27 06:45:57 davem Exp $ +/* $Id: memory.c,v 1.13 1998/01/30 10:59:03 jj Exp $ * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997 Michael A. Griffith (grif@acm.org) */ #include <linux/config.h> @@ -10,6 +11,7 @@ #include <linux/init.h> #include <asm/openprom.h> +#include <asm/sun4prom.h> #include <asm/oplib.h> /* This routine, for consistency, returns the ram parameters in the @@ -177,6 +179,21 @@ __initfunc(void prom_meminit(void)) prom_sortmemlist(prom_phys_avail); break; + case PROM_SUN4: +#ifdef CONFIG_SUN4 + /* how simple :) */ + prom_phys_total[0].start_adr = 0x0; + prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize); + prom_phys_total[0].theres_more = 0x0; + prom_prom_taken[0].start_adr = 0x0; + prom_prom_taken[0].num_bytes = 0x0; + prom_prom_taken[0].theres_more = 0x0; + prom_phys_avail[0].start_adr = 0x0; + prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); + prom_phys_avail[0].theres_more = 0x0; +#endif + break; + case PROM_AP1000: #if CONFIG_AP1000 /* really simple memory map */ @@ -189,9 +206,6 @@ __initfunc(void prom_meminit(void)) prom_phys_avail[0].start_adr = 0x00000000; prom_phys_avail[0].num_bytes = prom_phys_total[0].num_bytes; prom_phys_avail[0].theres_more = 0x0; - prom_sortmemlist(prom_phys_total); - prom_sortmemlist(prom_prom_taken); - prom_sortmemlist(prom_phys_avail); #endif default: break; diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c index fede033dd..d2ec600e1 100644 --- a/arch/sparc/prom/misc.c +++ b/arch/sparc/prom/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.15 1997/05/14 20:45:00 davem Exp $ +/* $Id: misc.c,v 1.16 1998/03/09 14:04:25 jj Exp $ * misc.c: Miscellaneous prom functions that don't belong * anywhere else. * @@ -13,8 +13,7 @@ #include <asm/oplib.h> #include <asm/auxio.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Reset and reboot the machine with the command 'bcommand'. */ void @@ -24,9 +23,7 @@ prom_reboot(char *bcommand) save_flags(flags); cli(); (*(romvec->pv_reboot))(bcommand); /* Never get here. */ - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); } @@ -42,9 +39,7 @@ prom_feval(char *fstring) (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring); else (*(romvec->pv_fortheval.v2_eval))(fstring); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); } @@ -74,9 +69,7 @@ prom_cmdline(void) install_obp_ticker(); save_flags(flags); cli(); (*(romvec->pv_abort))(); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); install_linux_ticker(); #ifdef CONFIG_SUN_AUXIO @@ -99,9 +92,7 @@ again: save_flags(flags); cli(); (*(romvec->pv_halt))(); /* Never get here. */ - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); goto again; /* PROM is out to get me -DaveM */ } diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c index 8f07f9d40..2346e3564 100644 --- a/arch/sparc/prom/mp.c +++ b/arch/sparc/prom/mp.c @@ -1,4 +1,4 @@ -/* $Id: mp.c,v 1.9 1997/05/14 20:45:01 davem Exp $ +/* $Id: mp.c,v 1.10 1998/03/09 14:04:26 jj Exp $ * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) * @@ -12,8 +12,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Start cpu with prom-tree node 'cpunode' using context described * by 'ctable_reg' in context 'ctx' at program counter 'pc'. @@ -38,9 +37,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha ret = (*(romvec->v3_cpustart))(cpunode, (int) ctable_reg, ctx, pc); break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return ret; @@ -67,9 +64,7 @@ prom_stopcpu(int cpunode) ret = (*(romvec->v3_cpustop))(cpunode); break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return ret; @@ -96,9 +91,7 @@ prom_idlecpu(int cpunode) ret = (*(romvec->v3_cpuidle))(cpunode); break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return ret; @@ -125,9 +118,7 @@ prom_restartcpu(int cpunode) ret = (*(romvec->v3_cpuresume))(cpunode); break; }; - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return ret; diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c index 7f7b1da54..b4fd3989e 100644 --- a/arch/sparc/prom/ranges.c +++ b/arch/sparc/prom/ranges.c @@ -1,4 +1,4 @@ -/* $Id: ranges.c,v 1.10 1997/12/19 12:37:18 jj Exp $ +/* $Id: ranges.c,v 1.11 1998/01/30 10:59:05 jj Exp $ * ranges.c: Handle ranges in newer proms for obio/sbus. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -68,7 +68,7 @@ prom_apply_obio_ranges(struct linux_prom_registers *regs, int nregs) void prom_apply_sbus_ranges(struct linux_sbus *sbus, struct linux_prom_registers *regs, int nregs, struct linux_sbus_device *sdev) { - if(sbus->num_sbus_ranges) { + if(sbus && sbus->num_sbus_ranges) { if(sdev && (sdev->ranges_applied == 0)) { sdev->ranges_applied = 1; prom_adjust_regs(regs, nregs, sbus->sbus_ranges, diff --git a/arch/sparc/prom/segment.c b/arch/sparc/prom/segment.c index 96b543727..62b3f8542 100644 --- a/arch/sparc/prom/segment.c +++ b/arch/sparc/prom/segment.c @@ -1,4 +1,4 @@ -/* $Id: segment.c,v 1.5 1997/05/14 20:45:02 davem Exp $ +/* $Id: segment.c,v 1.6 1998/03/09 14:04:27 jj Exp $ * segment.c: Prom routine to map segments in other contexts before * a standalone is completely mapped. This is for sun4 and * sun4c architectures only. @@ -12,8 +12,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; +extern void restore_current(void); /* Set physical segment 'segment' at virtual address 'vaddr' in * context 'ctx'. @@ -24,9 +23,7 @@ prom_putsegment(int ctx, unsigned long vaddr, int segment) unsigned long flags; save_flags(flags); cli(); (*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment); - __asm__ __volatile__("ld [%0], %%g6\n\t" : : - "r" (¤t_set[hard_smp_processor_id()]) : - "memory"); + restore_current(); restore_flags(flags); return; } diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c new file mode 100644 index 000000000..ce15ebb43 --- /dev/null +++ b/arch/sparc/prom/sun4prom.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 1996 The Australian National University. + * Copyright (C) 1996 Fujitsu Laboratories Limited + * Copyright (C) 1997 Michael A. Griffith (grif@acm.org) + * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us) + * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * + * This software may be distributed under the terms of the Gnu + * Public License version 2 or later + * + * fake a really simple Sun prom for the SUN4 + */ + +#include <linux/kernel.h> +#include <linux/string.h> +#include <asm/oplib.h> +#include <asm/idprom.h> +#include <asm/machines.h> +#include <asm/sun4prom.h> +#include <asm/asi.h> +#include <asm/contregs.h> +#include <linux/init.h> + +static struct linux_romvec sun4romvec; +static struct idprom sun4_idprom; + +struct property { + char *name; + char *value; + int length; +}; + +struct node { + int level; + struct property *properties; +}; + +struct property null_properties = { NULL, NULL, -1 }; + +struct property root_properties[] = { + {"device_type", "cpu", 4}, + {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)}, + {NULL, NULL, -1} +}; + +struct node nodes[] = { + { 0, &null_properties }, + { 0, root_properties }, + { -1,&null_properties } +}; + + +static int no_nextnode(int node) +{ + if (nodes[node].level == nodes[node+1].level) + return node+1; + return -1; +} + +static int no_child(int node) +{ + if (nodes[node].level == nodes[node+1].level-1) + return node+1; + return -1; +} + +static struct property *find_property(int node,char *name) +{ + struct property *prop = &nodes[node].properties[0]; + while (prop && prop->name) { + if (strcmp(prop->name,name) == 0) return prop; + prop++; + } + return NULL; +} + +static int no_proplen(int node,char *name) +{ + struct property *prop = find_property(node,name); + if (prop) return prop->length; + return -1; +} + +static int no_getprop(int node,char *name,char *value) +{ + struct property *prop = find_property(node,name); + if (prop) { + memcpy(value,prop->value,prop->length); + return 1; + } + return -1; +} + +static int no_setprop(int node,char *name,char *value,int len) +{ + return -1; +} + +static char *no_nextprop(int node,char *name) +{ + struct property *prop = find_property(node,name); + if (prop) return prop[1].name; + return NULL; +} + +static struct linux_nodeops sun4_nodeops = { + no_nextnode, + no_child, + no_proplen, + no_getprop, + no_setprop, + no_nextprop +}; + +static int synch_hook; + +__initfunc(struct linux_romvec *sun4_prom_init(void)) +{ + int i; + unsigned char x; + char *p; + + p = (char *)&sun4_idprom; + for (i = 0; i < sizeof(sun4_idprom); i++) { + __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) : + "r" (AC_IDPROM + i), "i" (ASI_CONTROL)); + *p++ = x; + } + + memset(&sun4romvec,0,sizeof(sun4romvec)); + + sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR; + + sun4romvec.pv_romvers = 40; + sun4romvec.pv_nodeops = &sun4_nodeops; + sun4romvec.pv_reboot = sun4_romvec->reboot; + sun4romvec.pv_abort = sun4_romvec->abortentry; + sun4romvec.pv_halt = sun4_romvec->exittomon; + sun4romvec.pv_synchook = (void (**)(void))&synch_hook; + sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap; + sun4romvec.pv_v0bootargs = sun4_romvec->bootParam; + sun4romvec.pv_nbgetchar = sun4_romvec->mayget; + sun4romvec.pv_nbputchar = sun4_romvec->mayput; + sun4romvec.pv_stdin = sun4_romvec->insource; + sun4romvec.pv_stdout = sun4_romvec->outsink; + + /* + * We turn on the LEDs to let folks without monitors or + * terminals know we booted. Nothing too fancy now. They + * are all on, except for LED 5, which blinks. When we + * have more time, we can teach the penguin to say "By your + * command" or "Activating turbo boost, Michael". :-) + */ + sun4_romvec->setLEDs(0x0); + + printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n", + sun4_romvec->monid, + sun4_romvec->romvecversion); + + return &sun4romvec; +} diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c index 616180e81..1256aacec 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.22 1997/09/25 02:19:22 davem Exp $ +/* $Id: tree.c,v 1.24 1998/03/09 14:04:29 jj Exp $ * tree.c: Basic device tree traversal/scanning for the Linux * prom library. * @@ -15,13 +15,7 @@ #include <asm/openprom.h> #include <asm/oplib.h> -/* XXX Let's get rid of this thing if we can... */ -extern struct task_struct *current_set[NR_CPUS]; - -/* Macro to restore "current" to the g6 register. */ -#define restore_current() __asm__ __volatile__("ld [%0], %%g6\n\t" : : \ - "r" (¤t_set[hard_smp_processor_id()]) : \ - "memory") +extern void restore_current(void); static char promlib_buf[128]; @@ -95,12 +89,11 @@ int prom_getproplen(int node, char *prop) int ret; unsigned long flags; - save_flags(flags); cli(); - if((!node) || (!prop)) - ret = -1; - else - ret = prom_nodeops->no_proplen(node, prop); + return -1; + + save_flags(flags); cli(); + ret = prom_nodeops->no_proplen(node, prop); restore_current(); restore_flags(flags); return ret; @@ -115,15 +108,12 @@ int prom_getproperty(int node, char *prop, char *buffer, int bufsize) int plen, ret; unsigned long flags; - save_flags(flags); cli(); - plen = prom_getproplen(node, prop); if((plen > bufsize) || (plen == 0) || (plen == -1)) - ret = -1; - else { - /* Ok, things seem all right. */ - ret = prom_nodeops->no_getprop(node, prop, buffer); - } + return -1; + /* Ok, things seem all right. */ + save_flags(flags); cli(); + ret = prom_nodeops->no_getprop(node, prop, buffer); restore_current(); restore_flags(flags); return ret; |