File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -232,8 +232,12 @@ void start(void)
232232 console_ops .close ();
233233
234234 kentry = (kernel_entry_t ) vmlinux .addr ;
235- if (ft_addr )
236- kentry (ft_addr , 0 , NULL );
235+ if (ft_addr ) {
236+ if (platform_ops .kentry )
237+ platform_ops .kentry (ft_addr , vmlinux .addr );
238+ else
239+ kentry (ft_addr , 0 , NULL );
240+ }
237241 else
238242 kentry ((unsigned long )initrd .addr , initrd .size ,
239243 loader_info .promptr );
Original file line number Diff line number Diff line change 1212
1313 .text
1414
15+ .globl opal_kentry
16+ opal_kentry:
17+ /* r3 is the fdt ptr */
18+ mtctr r4
19+ li r4, 0
20+ li r5, 0
21+ li r6, 0
22+ li r7, 0
23+ ld r11,opal@got(r2)
24+ ld r8,0 (r11)
25+ ld r9,8 (r11)
26+ bctr
27+
1528#define OPAL_CALL(name, token) \
1629 .globl name; \
1730name: \
Original file line number Diff line number Diff line change @@ -23,14 +23,25 @@ struct opal {
2323
2424static u32 opal_con_id ;
2525
26+ /* see opal-wrappers.S */
2627int64_t opal_console_write (int64_t term_number , u64 * length , const u8 * buffer );
2728int64_t opal_console_read (int64_t term_number , uint64_t * length , u8 * buffer );
2829int64_t opal_console_write_buffer_space (uint64_t term_number , uint64_t * length );
2930int64_t opal_console_flush (uint64_t term_number );
3031int64_t opal_poll_events (uint64_t * outstanding_event_mask );
3132
33+ void opal_kentry (unsigned long fdt_addr , void * vmlinux_addr );
34+
3235static int opal_con_open (void )
3336{
37+ /*
38+ * When OPAL loads the boot kernel it stashes the OPAL base and entry
39+ * address in r8 and r9 so the kernel can use the OPAL console
40+ * before unflattening the devicetree. While executing the wrapper will
41+ * probably trash r8 and r9 so this kentry hook restores them before
42+ * entering the decompressed kernel.
43+ */
44+ platform_ops .kentry = opal_kentry ;
3445 return 0 ;
3546}
3647
Original file line number Diff line number Diff line change @@ -30,6 +30,7 @@ struct platform_ops {
3030 void * (* realloc )(void * ptr , unsigned long size );
3131 void (* exit )(void );
3232 void * (* vmlinux_alloc )(unsigned long size );
33+ void (* kentry )(unsigned long fdt_addr , void * vmlinux_addr );
3334};
3435extern struct platform_ops platform_ops ;
3536
Original file line number Diff line number Diff line change 1414
1515#include <linux/threads.h>
1616#include <linux/kprobes.h>
17+ #include <asm/cacheflush.h>
18+ #include <asm/checksum.h>
19+ #include <asm/uaccess.h>
20+ #include <asm/epapr_hcalls.h>
1721
1822#include <uapi/asm/ucontext.h>
1923
@@ -109,4 +113,12 @@ void early_setup_secondary(void);
109113/* time */
110114void accumulate_stolen_time (void );
111115
116+ /* misc runtime */
117+ extern u64 __bswapdi2 (u64 );
118+ extern s64 __lshrdi3 (s64 , int );
119+ extern s64 __ashldi3 (s64 , int );
120+ extern s64 __ashrdi3 (s64 , int );
121+ extern int __cmpdi2 (s64 , s64 );
122+ extern int __ucmpdi2 (u64 , u64 );
123+
112124#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
Original file line number Diff line number Diff line change 2828 * Individual features below.
2929 */
3030
31+ /*
32+ * Kernel read only support.
33+ * We added the ppp value 0b110 in ISA 2.04.
34+ */
35+ #define MMU_FTR_KERNEL_RO ASM_CONST(0x00004000)
36+
3137/*
3238 * We need to clear top 16bits of va (from the remaining 64 bits )in
3339 * tlbie* instructions
103109#define MMU_FTRS_POWER4 MMU_FTRS_DEFAULT_HPTE_ARCH_V2
104110#define MMU_FTRS_PPC970 MMU_FTRS_POWER4 | MMU_FTR_TLBIE_CROP_VA
105111#define MMU_FTRS_POWER5 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
106- #define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
107- #define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
108- #define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
109- #define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
112+ #define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
113+ #define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
114+ #define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
115+ #define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
110116#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
111117 MMU_FTR_CI_LARGE_PAGE
112118#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
Original file line number Diff line number Diff line change 355355#define LPCR_PECE0 ASM_CONST(0x0000000000004000) /* ext. exceptions can cause exit */
356356#define LPCR_PECE1 ASM_CONST(0x0000000000002000) /* decrementer can cause exit */
357357#define LPCR_PECE2 ASM_CONST(0x0000000000001000) /* machine check etc can cause exit */
358+ #define LPCR_PECE_HVEE ASM_CONST(0x0000400000000000) /* P9 Wakeup on HV interrupts */
358359#define LPCR_MER ASM_CONST(0x0000000000000800) /* Mediated External Exception */
359360#define LPCR_MER_SH 11
360361#define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */
Original file line number Diff line number Diff line change @@ -98,8 +98,8 @@ _GLOBAL(__setup_cpu_power9)
9898 li r0,0
9999 mtspr SPRN_LPID,r0
100100 mfspr r3,SPRN_LPCR
101- ori r3, r3, LPCR_PECEDH
102- ori r3, r3, LPCR_HVICE
101+ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
102+ or r3, r3, r4
103103 bl __init_LPCR
104104 bl __init_HFSCR
105105 bl __init_tlb_power9
@@ -118,8 +118,8 @@ _GLOBAL(__restore_cpu_power9)
118118 li r0,0
119119 mtspr SPRN_LPID,r0
120120 mfspr r3,SPRN_LPCR
121- ori r3, r3, LPCR_PECEDH
122- ori r3, r3, LPCR_HVICE
121+ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
122+ or r3, r3, r4
123123 bl __init_LPCR
124124 bl __init_HFSCR
125125 bl __init_tlb_power9
Original file line number Diff line number Diff line change @@ -193,8 +193,12 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
193193 /*
194194 * Kernel read only mapped with ppp bits 0b110
195195 */
196- if (!(pteflags & _PAGE_WRITE ))
197- rflags |= (HPTE_R_PP0 | 0x2 );
196+ if (!(pteflags & _PAGE_WRITE )) {
197+ if (mmu_has_feature (MMU_FTR_KERNEL_RO ))
198+ rflags |= (HPTE_R_PP0 | 0x2 );
199+ else
200+ rflags |= 0x3 ;
201+ }
198202 } else {
199203 if (pteflags & _PAGE_RWX )
200204 rflags |= 0x2 ;
You can’t perform that action at this time.
0 commit comments