[SPARC32]: Fix sun4d sbus and current handling.
Linux Kernel Mailing List <[email protected]> Wed, 16 Mar 2005 18:57:39 +0000
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1560.1.6, 2005/03/16 10:57:39-08:00, [email protected] [SPARC32]: Fix sun4d sbus and current handling. - ASI_M_VIKING_TMP2 is only available on SuperSparc-I so we cannot use it to store the current task pointer. Use ASI_M_VIKING_TMP1 instead which is available on all sun4d processors. - Apply sun4d IOUNIT ranges to SBUS bus ranges. Signed-off-by: David S. Miller <[email protected]> arch/sparc/kernel/sun4d_smp.c | 18 +++++------------- arch/sparc/mm/io-unit.c | 2 +- arch/sparc/prom/ranges.c | 2 +- drivers/sbus/sbus.c | 16 ++++++++++++++++ include/asm-sparc/asi.h | 3 ++- include/asm-sparc/oplib.h | 3 +++ include/asm-sparc/winmacro.h | 9 ++++++--- 7 files changed, 34 insertions(+), 19 deletions(-) diff -Nru a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c --- a/arch/sparc/kernel/sun4d_smp.c 2005-03-16 15:02:54 -08:00 +++ b/arch/sparc/kernel/sun4d_smp.c 2005-03-16 15:02:54 -08:00 @@ -132,8 +132,7 @@ /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" - "sta %%g6, [%%g0] %1\n\t" - : : "r" (¤t_set[cpuid]), "i" (ASI_M_VIKING_TMP2) + : : "r" (¤t_set[cpuid]) : "memory" /* paranoid */); cpu_leds[cpuid] = 0x9; @@ -494,25 +493,18 @@ void __init smp4d_blackbox_current(unsigned *addr) { - /* We have a nice Linux current register :) */ - int rd = addr[1] & 0x3e000000; + int rd = *addr & 0x3e000000; - addr[0] = 0x10800006; /* b .+24 */ - addr[1] = 0xc0800820 | rd; /* lda [%g0] ASI_M_VIKING_TMP2, reg */ + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ + addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */ + addr[4] = 0x01000000; /* nop */ } void __init sun4d_init_smp(void) { int i; - extern unsigned int patchme_store_new_current[]; extern unsigned int t_nmi[], linux_trap_ipi15_sun4d[], linux_trap_ipi15_sun4m[]; - /* Store current into Linux current register :) */ - __asm__ __volatile__("sta %%g6, [%%g0] %0" : : "i"(ASI_M_VIKING_TMP2)); - - /* Patch switch_to */ - patchme_store_new_current[0] = (patchme_store_new_current[0] & 0x3e000000) | 0xc0a00820; - /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); diff -Nru a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c --- a/arch/sparc/mm/io-unit.c 2005-03-16 15:02:54 -08:00 +++ b/arch/sparc/mm/io-unit.c 2005-03-16 15:02:54 -08:00 @@ -188,7 +188,7 @@ pte_t *ptep; long i; - pgdp = pgd_offset(init_task.mm, addr); + pgdp = pgd_offset(&init_mm, addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset(pmdp, addr); diff -Nru a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c --- a/arch/sparc/prom/ranges.c 2005-03-16 15:02:54 -08:00 +++ b/arch/sparc/prom/ranges.c 2005-03-16 15:02:54 -08:00 @@ -34,7 +34,7 @@ } } -static void +void prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1, struct linux_prom_ranges *ranges2, int nranges2) { diff -Nru a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c --- a/drivers/sbus/sbus.c 2005-03-16 15:02:54 -08:00 +++ b/drivers/sbus/sbus.c 2005-03-16 15:02:54 -08:00 @@ -215,6 +215,8 @@ * prom_sbus_ranges_init(), with all sun4d stuff cut away. * Ask DaveM what is going on here, how is sun4d supposed to work... XXX */ +/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ + static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus) { int len; @@ -227,6 +229,20 @@ return; } sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges); +#ifdef CONFIG_SPARC32 + if (sparc_cpu_model == sun4d) { + struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; + int num_iounit_ranges; + + len = prom_getproperty(parent_node, "ranges", + (char *) iounit_ranges, + sizeof (iounit_ranges)); + if (len != -1) { + num_iounit_ranges = (len/sizeof(struct linux_prom_ranges)); + prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges); + } + } +#endif } static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, diff -Nru a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h --- a/include/asm-sparc/asi.h 2005-03-16 15:02:54 -08:00 +++ b/include/asm-sparc/asi.h 2005-03-16 15:02:54 -08:00 @@ -104,7 +104,8 @@ #define ASI_M_DCDR 0x39 /* Data Cache Diagnostics Register rw, ss */ #define ASI_M_VIKING_TMP1 0x40 /* Emulation temporary 1 on Viking */ -#define ASI_M_VIKING_TMP2 0x41 /* Emulation temporary 2 on Viking */ +/* only available on SuperSparc I */ +/* #define ASI_M_VIKING_TMP2 0x41 */ /* Emulation temporary 2 on Viking */ #define ASI_M_ACTION 0x4c /* Breakpoint Action Register (GNU/Viking) */ diff -Nru a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h --- a/include/asm-sparc/oplib.h 2005-03-16 15:02:54 -08:00 +++ b/include/asm-sparc/oplib.h 2005-03-16 15:02:54 -08:00 @@ -296,6 +296,9 @@ /* Dorking with Bus ranges... */ +extern void prom_adjust_ranges(struct linux_prom_ranges *, int, + struct linux_prom_ranges *, int); + /* Apply promlib probes OBIO ranges to registers. */ extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); diff -Nru a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h --- a/include/asm-sparc/winmacro.h 2005-03-16 15:02:54 -08:00 +++ b/include/asm-sparc/winmacro.h 2005-03-16 15:02:54 -08:00 @@ -113,9 +113,12 @@ and %idreg, 0xc, %idreg; \ ld [%idreg + %dest_reg], %dest_reg; -/* Sliiick. We have a Linux current register :) -jj */ -#define LOAD_CURRENT4D(dest_reg) \ - lda [%g0] ASI_M_VIKING_TMP2, %dest_reg; +#define LOAD_CURRENT4D(dest_reg, idreg) \ + lda [%g0] ASI_M_VIKING_TMP1, %idreg; \ + sethi %hi(C_LABEL(current_set)), %dest_reg; \ + sll %idreg, 2, %idreg; \ + or %dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \ + ld [%idreg + %dest_reg], %dest_reg; /* Blackbox - take care with this... - check smp4m and smp4d before changing this. */ #define LOAD_CURRENT(dest_reg, idreg) \