Commit d4c186bd authored by Paul Mackerras's avatar Paul Mackerras

Merge bk://ppc@ppc.bkbits.net/for-linus-ppc

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 230ac729 2cd038d6
This diff is collapsed.
...@@ -32,6 +32,7 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o ...@@ -32,6 +32,7 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
......
...@@ -198,7 +198,7 @@ udelay: ...@@ -198,7 +198,7 @@ udelay:
* timebase_period_ns defaults to 60 (16.6MHz) */ * timebase_period_ns defaults to 60 (16.6MHz) */
lis r5,timebase_period_ns@ha lis r5,timebase_period_ns@ha
lwz r5,timebase_period_ns@l(r5) lwz r5,timebase_period_ns@l(r5)
addi r4,r4,r5 add r4,r4,r5
addi r4,r4,-1 addi r4,r4,-1
divw r4,r4,r5 /* BUS ticks */ divw r4,r4,r5 /* BUS ticks */
1: mftbu r5 1: mftbu r5
......
...@@ -15,6 +15,7 @@ extra-$(CONFIG_40x) := head_4xx.o ...@@ -15,6 +15,7 @@ extra-$(CONFIG_40x) := head_4xx.o
extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds.s extra-y += vmlinux.lds.s
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
......
...@@ -28,11 +28,13 @@ extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* ...@@ -28,11 +28,13 @@ extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec*
extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec); extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ #define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
!defined(CONFIG_POWER3)) !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4))
/* This table only contains "desktop" CPUs, it need to be filled with embedded /* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well... * ones as well...
...@@ -44,9 +46,11 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spe ...@@ -44,9 +46,11 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spe
* support * support
*/ */
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC #define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
#define PPC_FEATURE_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
#else #else
#define CPU_FTR_ALTIVEC_COMP 0 #define CPU_FTR_ALTIVEC_COMP 0
#define PPC_FEATURE_ALTIVEC_COMP 0
#endif #endif
struct cpu_spec cpu_specs[] = { struct cpu_spec cpu_specs[] = {
...@@ -195,7 +199,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -195,7 +199,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP, CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32, 32, 32,
__setup_cpu_7400 __setup_cpu_7400
}, },
...@@ -204,7 +208,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -204,7 +208,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP, CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_7400 __setup_cpu_7400
}, },
...@@ -213,7 +217,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -213,7 +217,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP, CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_7410 __setup_cpu_7410
}, },
...@@ -222,7 +226,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -222,7 +226,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450, CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -232,7 +236,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -232,7 +236,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_L3_DISABLE_NAP, CPU_FTR_L3_DISABLE_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -241,7 +245,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -241,7 +245,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR, CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -250,7 +254,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -250,7 +254,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS, CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -260,7 +264,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -260,7 +264,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_L3_DISABLE_NAP | CPU_FTR_HAS_HIGH_BATS, CPU_FTR_L3_DISABLE_NAP | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -270,7 +274,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -270,7 +274,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS, CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -280,7 +284,7 @@ struct cpu_spec cpu_specs[] = { ...@@ -280,7 +284,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS, CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32, 32, 32,
__setup_cpu_745x __setup_cpu_745x
}, },
...@@ -329,6 +333,23 @@ struct cpu_spec cpu_specs[] = { ...@@ -329,6 +333,23 @@ struct cpu_spec cpu_specs[] = {
__setup_cpu_power3 __setup_cpu_power3
}, },
#endif /* CONFIG_PPC64BRIDGE */ #endif /* CONFIG_PPC64BRIDGE */
#ifdef CONFIG_POWER4
{ /* Power4 */
0xffff0000, 0x00350000, "Power4",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
COMMON_PPC | PPC_FEATURE_64,
128, 128,
__setup_cpu_power4
},
{ /* PPC970 */
0xffff0000, 0x00390000, "PPC970",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_64 | PPC_FEATURE_ALTIVEC_COMP,
128, 128,
__setup_cpu_ppc970
},
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8xx #ifdef CONFIG_8xx
{ /* 8xx */ { /* 8xx */
0xffff0000, 0x00500000, "8xx", 0xffff0000, 0x00500000, "8xx",
......
...@@ -140,6 +140,18 @@ __start: ...@@ -140,6 +140,18 @@ __start:
mr r28,r6 mr r28,r6
mr r27,r7 mr r27,r7
li r24,0 /* cpu # */ li r24,0 /* cpu # */
#ifdef CONFIG_POWER4
/*
* On the PPC970, we have to turn off real-mode cache inhibit
* early, before we first turn the MMU off.
*/
mfspr r0,SPRN_PVR
srwi r0,r0,16
cmpwi r0,0x39
beql ppc970_setup_hid
#endif /* CONFIG_POWER4 */
/* /*
* early_init() does the early machine identification and does * early_init() does the early machine identification and does
* the necessary low-level setup and clears the BSS * the necessary low-level setup and clears the BSS
...@@ -160,6 +172,7 @@ __start: ...@@ -160,6 +172,7 @@ __start:
*/ */
bl mmu_off bl mmu_off
__after_mmu_off: __after_mmu_off:
#ifndef CONFIG_POWER4
bl clear_bats bl clear_bats
bl flush_tlbs bl flush_tlbs
...@@ -167,6 +180,28 @@ __after_mmu_off: ...@@ -167,6 +180,28 @@ __after_mmu_off:
#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
bl setup_disp_bat bl setup_disp_bat
#endif #endif
#else /* CONFIG_POWER4 */
/*
* Load up the SDR1 and segment register values now
* since we don't have the BATs.
* Also make sure we are running in 32-bit mode.
*/
bl reloc_offset
addis r14,r3,_SDR1@ha /* get the value from _SDR1 */
lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */
mtspr SDR1,r14
slbia
lis r4,0x2000 /* set pseudo-segment reg 12 */
ori r5,r4,0x0ccc
mtsr 12,r5
ori r4,r4,0x0888 /* set pseudo-segment reg 8 */
mtsr 8,r4 /* (for access to serial port) */
mfmsr r0
clrldi r0,r0,1
sync
mtmsr r0
isync
#endif /* CONFIG_POWER4 */
/* /*
* Call setup_cpu for CPU 0 and initialize 6xx Idle * Call setup_cpu for CPU 0 and initialize 6xx Idle
...@@ -178,6 +213,10 @@ __after_mmu_off: ...@@ -178,6 +213,10 @@ __after_mmu_off:
bl reloc_offset bl reloc_offset
bl init_idle_6xx bl init_idle_6xx
#endif /* CONFIG_6xx */ #endif /* CONFIG_6xx */
#ifdef CONFIG_POWER4
bl reloc_offset
bl init_idle_power4
#endif /* CONFIG_POWER4 */
#ifndef CONFIG_APUS #ifndef CONFIG_APUS
...@@ -683,12 +722,21 @@ DataStoreTLBMiss: ...@@ -683,12 +722,21 @@ DataStoreTLBMiss:
mtcrf 0x80,r3 mtcrf 0x80,r3
rfi rfi
#ifndef CONFIG_ALTIVEC
#define AltivecAssistException UnknownException
#endif
EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE) EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE) EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
#ifdef CONFIG_POWER4
EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE) EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
#else /* !CONFIG_POWER4 */
EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE) EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
#endif /* CONFIG_POWER4 */
EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE) EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE) EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE) EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
...@@ -1199,6 +1247,10 @@ __secondary_start: ...@@ -1199,6 +1247,10 @@ __secondary_start:
lis r3,-KERNELBASE@h lis r3,-KERNELBASE@h
bl init_idle_6xx bl init_idle_6xx
#endif /* CONFIG_6xx */ #endif /* CONFIG_6xx */
#ifdef CONFIG_POWER4
lis r3,-KERNELBASE@h
bl init_idle_power4
#endif /* CONFIG_POWER4 */
/* get current_thread_info and current */ /* get current_thread_info and current */
lis r1,secondary_ti@ha lis r1,secondary_ti@ha
...@@ -1226,6 +1278,7 @@ __secondary_start: ...@@ -1226,6 +1278,7 @@ __secondary_start:
/* enable MMU and jump to start_secondary */ /* enable MMU and jump to start_secondary */
li r4,MSR_KERNEL li r4,MSR_KERNEL
FIX_SRR1(r4,r5)
lis r3,start_secondary@h lis r3,start_secondary@h
ori r3,r3,start_secondary@l ori r3,r3,start_secondary@l
mtspr SRR0,r3 mtspr SRR0,r3
...@@ -1240,6 +1293,10 @@ __secondary_start: ...@@ -1240,6 +1293,10 @@ __secondary_start:
*/ */
_GLOBAL(__setup_cpu_power3) _GLOBAL(__setup_cpu_power3)
blr blr
_GLOBAL(__setup_cpu_power4)
blr
_GLOBAL(__setup_cpu_ppc970)
blr
_GLOBAL(__setup_cpu_generic) _GLOBAL(__setup_cpu_generic)
blr blr
...@@ -1247,6 +1304,13 @@ _GLOBAL(__setup_cpu_generic) ...@@ -1247,6 +1304,13 @@ _GLOBAL(__setup_cpu_generic)
_GLOBAL(__save_cpu_setup) _GLOBAL(__save_cpu_setup)
blr blr
_GLOBAL(__restore_cpu_setup) _GLOBAL(__restore_cpu_setup)
#ifdef CONFIG_POWER4
/* turn off real-mode cache inhibit on the PPC970 */
mfspr r0,SPRN_PVR
srwi r0,r0,16
cmpwi r0,0x39
beq ppc970_setup_hid
#endif
blr blr
#endif /* CONFIG_6xx */ #endif /* CONFIG_6xx */
...@@ -1256,6 +1320,11 @@ _GLOBAL(__restore_cpu_setup) ...@@ -1256,6 +1320,11 @@ _GLOBAL(__restore_cpu_setup)
* IR=0 and DR=0. * IR=0 and DR=0.
*/ */
load_up_mmu: load_up_mmu:
sync /* Force all PTE updates to finish */
isync
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
TLBSYNC /* ... on all CPUs */
/* Load the SDR1 register (hash table base & size) */ /* Load the SDR1 register (hash table base & size) */
lis r6,_SDR1@ha lis r6,_SDR1@ha
tophys(r6,r6) tophys(r6,r6)
...@@ -1274,6 +1343,7 @@ load_up_mmu: ...@@ -1274,6 +1343,7 @@ load_up_mmu:
addi r3,r3,0x111 /* increment VSID */ addi r3,r3,0x111 /* increment VSID */
addis r4,r4,0x1000 /* address of next segment */ addis r4,r4,0x1000 /* address of next segment */
bdnz 3b bdnz 3b
#ifndef CONFIG_POWER4
/* Load the BAT registers with the values set up by MMU_init. /* Load the BAT registers with the values set up by MMU_init.
MMU_init takes care of whether we're on a 601 or not. */ MMU_init takes care of whether we're on a 601 or not. */
mfpvr r3 mfpvr r3
...@@ -1286,6 +1356,7 @@ load_up_mmu: ...@@ -1286,6 +1356,7 @@ load_up_mmu:
LOAD_BAT(1,r3,r4,r5) LOAD_BAT(1,r3,r4,r5)
LOAD_BAT(2,r3,r4,r5) LOAD_BAT(2,r3,r4,r5)
LOAD_BAT(3,r3,r4,r5) LOAD_BAT(3,r3,r4,r5)
#endif /* CONFIG_POWER4 */
blr blr
/* /*
...@@ -1349,15 +1420,9 @@ start_here: ...@@ -1349,15 +1420,9 @@ start_here:
SYNC SYNC
RFI RFI
/* Load up the kernel context */ /* Load up the kernel context */
2: 2: bl load_up_mmu
sync /* Force all PTE updates to finish */
ISYNC_601
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
TLBSYNC /* ... on all CPUs */
bl load_up_mmu
#ifdef CONFIG_BDI_SWITCH
/* Add helper information for the Abatron bdiGDB debugger. /* Add helper information for the Abatron bdiGDB debugger.
* We do this here because we know the mmu is disabled, and * We do this here because we know the mmu is disabled, and
* will be enabled for real in just a few instructions. * will be enabled for real in just a few instructions.
...@@ -1369,6 +1434,7 @@ start_here: ...@@ -1369,6 +1434,7 @@ start_here:
ori r6, r6, swapper_pg_dir@l ori r6, r6, swapper_pg_dir@l
tophys(r5, r5) tophys(r5, r5)
stw r6, 0(r5) stw r6, 0(r5)
#endif /* CONFIG_BDI_SWITCH */
/* Now turn on the MMU for real! */ /* Now turn on the MMU for real! */
li r4,MSR_KERNEL li r4,MSR_KERNEL
...@@ -1493,6 +1559,7 @@ mmu_off: ...@@ -1493,6 +1559,7 @@ mmu_off:
sync sync
RFI RFI
#ifndef CONFIG_POWER4
/* /*
* Use the first pair of BAT registers to map the 1st 16MB * Use the first pair of BAT registers to map the 1st 16MB
* of RAM to KERNELBASE. From this point on we can't safely * of RAM to KERNELBASE. From this point on we can't safely
...@@ -1566,6 +1633,41 @@ setup_disp_bat: ...@@ -1566,6 +1633,41 @@ setup_disp_bat:
#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
#else /* CONFIG_POWER4 */
ppc970_setup_hid:
li r0,0
sync
mtspr 0x3f4,r0
isync
sync
mtspr 0x3f6,r0
isync
mfspr r0,SPRN_HID0
li r11,1 /* clear DOZE, NAP and SLEEP */
rldimi r0,r11,52,8 /* set DPM */
mtspr SPRN_HID0,r0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
sync
isync
mfspr r0,SPRN_HID1
li r11,0x1200 /* enable i-fetch cacheability */
sldi r11,r11,44 /* and prefetch */
or r0,r0,r11
mtspr SPRN_HID1,r0
mtspr SPRN_HID1,r0
isync
li r0,0
sync
mtspr 0x137,0
isync
blr
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8260 #ifdef CONFIG_8260
/* Jump into the system reset for the rom. /* Jump into the system reset for the rom.
* We first disable the MMU, and then jump to the ROM reset address. * We first disable the MMU, and then jump to the ROM reset address.
......
/*
* This file contains the power_save function for 6xx & 7xxx CPUs
* rewritten in assembler
*
* Warning ! This code assumes that if your machine has a 750fx
* it will have PLL 1 set to low speed mode (used during NAP/DOZE).
* if this is not the case some additional changes will have to
* be done to check a runtime var (a bit like powersave-nap)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/threads.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#undef DEBUG
.text
/*
* Init idle, called at early CPU setup time from head.S for each CPU
* Make sure no rest of NAP mode remains in HID0, save default
* values for some CPU specific registers. Called with r24
* containing CPU number and r3 reloc offset
*/
.globl init_idle_power4
init_idle_power4:
BEGIN_FTR_SECTION
mfspr r4,SPRN_HID0
rlwinm r4,r4,0,10,8 /* Clear NAP */
mtspr SPRN_HID0, r4
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
blr
/*
* Here is the power_save_6xx function. This could eventually be
* split into several functions & changing the function pointer
* depending on the various features.
*/
.globl power4_idle
power4_idle:
/* Check if we can nap or doze, put HID0 mask in r3
*/
lis r3, 0
BEGIN_FTR_SECTION
/* We must dynamically check for the NAP feature as it
* can be cleared by CPU init after the fixups are done
*/
lis r4,cur_cpu_spec@ha
lwz r4,cur_cpu_spec@l(r4)
lwz r4,CPU_SPEC_FEATURES(r4)
andi. r0,r4,CPU_FTR_CAN_NAP
beq 1f
/* Now check if user or arch enabled NAP mode */
lis r4,powersave_nap@ha
lwz r4,powersave_nap@l(r4)
cmpi 0,r4,0
beq 1f
lis r3,HID0_NAP@h
1:
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
cmpi 0,r3,0
beqlr
/* Clear MSR:EE */
mfmsr r7
rlwinm r0,r7,0,17,15
mtmsr r0
/* Check current_thread_info()->flags */
rlwinm r4,r1,0,0,18
lwz r4,TI_FLAGS(r4)
andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
mtmsr r7 /* out of line this ? */
blr
1:
/* Go to NAP now */
mfspr r4,SPRN_HID0
lis r5,(HID0_NAP|HID0_SLEEP)@h
andc r4,r4,r5
or r4,r4,r3
oris r4,r4,HID0_DPM@h /* that should be done once for all */
mtspr SPRN_HID0,r4
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
BEGIN_FTR_SECTION
DSSALL
sync
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
ori r7,r7,MSR_EE /* Could be ommited (already set) */
oris r7,r7,MSR_POW@h
sync
isync
mtmsr r7
isync
sync
blr
.globl powersave_nap
powersave_nap:
.long 0
...@@ -54,6 +54,7 @@ extern void kgdb_map_scc(void); ...@@ -54,6 +54,7 @@ extern void kgdb_map_scc(void);
#endif #endif
extern void ppc6xx_idle(void); extern void ppc6xx_idle(void);
extern void power4_idle(void);
extern boot_infos_t *boot_infos; extern boot_infos_t *boot_infos;
char saved_command_line[256]; char saved_command_line[256];
...@@ -529,9 +530,12 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -529,9 +530,12 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5,
strcpy(cmd_line, CONFIG_CMDLINE); strcpy(cmd_line, CONFIG_CMDLINE);
#endif /* CONFIG_CMDLINE */ #endif /* CONFIG_CMDLINE */
#if defined(CONFIG_6xx) #ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle; ppc_md.power_save = ppc6xx_idle;
#endif #endif
#ifdef CONFIG_POWER4
ppc_md.power_save = power4_idle;
#endif
platform_init(r3, r4, r5, r6, r7); platform_init(r3, r4, r5, r6, r7);
......
...@@ -577,6 +577,17 @@ TAUException(struct pt_regs *regs) ...@@ -577,6 +577,17 @@ TAUException(struct pt_regs *regs)
} }
#endif /* CONFIG_INT_TAU */ #endif /* CONFIG_INT_TAU */
#ifdef CONFIG_ALTIVEC
void
AltivecAssistException(struct pt_regs *regs)
{
if (regs->msr & MSR_VEC)
giveup_altivec(current);
/* XXX quick hack for now: set the non-Java bit in the VSCR */
current->thread.vscr.u[3] |= 0x10000;
}
#endif /* CONFIG_ALTIVEC */
void __init trap_init(void) void __init trap_init(void)
{ {
} }
...@@ -4,6 +4,7 @@ config 4xx ...@@ -4,6 +4,7 @@ config 4xx
default y default y
menu "IBM 4xx options" menu "IBM 4xx options"
depends on 4xx
choice choice
prompt "Machine Type" prompt "Machine Type"
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
* vector that will be called by the ROM on wakeup * vector that will be called by the ROM on wakeup
*/ */
_GLOBAL(low_sleep_handler) _GLOBAL(low_sleep_handler)
#ifndef CONFIG_6xx
blr
#else
mflr r0 mflr r0
stw r0,4(r1) stw r0,4(r1)
stwu r1,-SL_SIZE(r1) stwu r1,-SL_SIZE(r1)
...@@ -381,4 +384,6 @@ turn_on_mmu: ...@@ -381,4 +384,6 @@ turn_on_mmu:
sleep_storage: sleep_storage:
.long 0 .long 0
.balign L1_CACHE_LINE_SIZE, 0 .balign L1_CACHE_LINE_SIZE, 0
#endif /* CONFIG_6xx */
.section .text .section .text
...@@ -434,9 +434,14 @@ setup_disp_fake_bi(ihandle dp) ...@@ -434,9 +434,14 @@ setup_disp_fake_bi(ihandle dp)
if (strcmp(name, "valkyrie") == 0) if (strcmp(name, "valkyrie") == 0)
address += 0x1000; address += 0x1000;
#ifdef CONFIG_POWER4
extern int boot_text_mapped;
btext_setup_display(width, height, depth, pitch, address);
boot_text_mapped = 0;
#else
btext_setup_display(width, height, depth, pitch, address); btext_setup_display(width, height, depth, pitch, address);
btext_prepare_BAT(); btext_prepare_BAT();
#endif
#endif /* CONFIG_BOOTX_TEXT */ #endif /* CONFIG_BOOTX_TEXT */
} }
...@@ -644,6 +649,72 @@ prom_hold_cpus(unsigned long mem) ...@@ -644,6 +649,72 @@ prom_hold_cpus(unsigned long mem)
} }
} }
#ifdef CONFIG_POWER4
/*
* Set up a hash table with a set of entries in it to map the
* first 64MB of RAM. This is used on 64-bit machines since
* some of them don't have BATs.
* We assume the PTE will fit in the primary PTEG.
*/
static inline void make_pte(unsigned long htab, unsigned int hsize,
unsigned int va, unsigned int pa, int mode)
{
unsigned int *pteg;
unsigned int hash, i, vsid;
vsid = ((va >> 28) * 0x111) << 12;
hash = ((va ^ vsid) >> 5) & 0x7fff80;
pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
for (i = 0; i < 8; ++i, pteg += 4) {
if ((pteg[1] & 1) == 0) {
pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
pteg[3] = pa | mode;
break;
}
}
}
extern unsigned long _SDR1;
extern PTE *Hash;
extern unsigned long Hash_size;
static void __init
prom_alloc_htab(void)
{
unsigned int hsize;
unsigned long htab;
unsigned int addr;
/*
* Because of OF bugs we can't use the "claim" client
* interface to allocate memory for the hash table.
* This code is only used on 64-bit PPCs, and the only
* 64-bit PPCs at the moment are RS/6000s, and their
* OF is based at 0xc00000 (the 12M point), so we just
* arbitrarily use the 0x800000 - 0xc00000 region for the
* hash table.
* -- paulus.
*/
hsize = 4 << 20; /* POWER4 has no BATs */
htab = (8 << 20);
call_prom("claim", 3, 1, htab, hsize, 0);
Hash = (void *)(htab + KERNELBASE);
Hash_size = hsize;
_SDR1 = htab + __ilog2(hsize) - 18;
/*
* Put in PTEs for the first 64MB of RAM
*/
cacheable_memzero((void *)htab, hsize);
for (addr = 0; addr < 0x4000000; addr += 0x1000)
make_pte(htab, hsize, addr + KERNELBASE, addr,
_PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
make_pte(htab, hsize, 0x80013000, 0x80013000,
_PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
}
#endif /* CONFIG_POWER4 */
static void __init static void __init
prom_instantiate_rtas(void) prom_instantiate_rtas(void)
{ {
...@@ -745,6 +816,13 @@ prom_init(int r3, int r4, prom_entry pp) ...@@ -745,6 +816,13 @@ prom_init(int r3, int r4, prom_entry pp)
prom_instantiate_rtas(); prom_instantiate_rtas();
#ifdef CONFIG_POWER4
/*
* Find out how much memory we have and allocate a
* suitably-sized hash table.
*/
prom_alloc_htab();
#endif
mem = check_display(mem); mem = check_display(mem);
prom_print("copying OF device tree..."); prom_print("copying OF device tree...");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment