Commit bdc2b03d authored by Anton Blanchard's avatar Anton Blanchard

ppc64: Allocate RTAS above OF, from Peter Bergner

parent 1f71a6f5
...@@ -153,8 +153,9 @@ _GLOBAL(__secondary_hold) ...@@ -153,8 +153,9 @@ _GLOBAL(__secondary_hold)
*/ */
/* /*
* We make as much of the exception code common between native Pseries * We make as much of the exception code common between native
* and Iseries LPAR implementations as possible. * exception handlers (including pSeries LPAR) and iSeries LPAR
* implementations as possible.
*/ */
/* /*
...@@ -1340,17 +1341,10 @@ _STATIC(__after_prom_start) ...@@ -1340,17 +1341,10 @@ _STATIC(__after_prom_start)
/* executed here. */ /* executed here. */
LOADADDR(r0, 4f) /* Jump to the copy of this code */ LOADADDR(r0, 4f) /* Jump to the copy of this code */
mtctr r0 /* that we just made */ mtctr r0 /* that we just made/relocated */
bctr bctr
4: LOADADDR(r9,rtas) 4: LOADADDR(r5,klimit)
sub r9,r9,r26
ld r5,RTASBASE(r9) /* get the value of rtas->base */
ld r9,RTASSIZE(r9) /* get the value of rtas->size */
bl .copy_and_flush /* copy upto rtas->base */
add r6,r6,r9 /* then skip over rtas->size bytes */
LOADADDR(r5,klimit)
sub r5,r5,r26 sub r5,r5,r26
ld r5,0(r5) /* get the value of klimit */ ld r5,0(r5) /* get the value of klimit */
sub r5,r5,r27 sub r5,r5,r27
...@@ -1675,9 +1669,6 @@ _STATIC(start_here_pSeries) ...@@ -1675,9 +1669,6 @@ _STATIC(start_here_pSeries)
addi r2,r2,0x4000 addi r2,r2,0x4000
sub r2,r2,r26 sub r2,r2,r26
/* Init naca->debug_switch so it can be used in stab & htab init. */
bl .ppcdbg_initialize
/* Get the pointer to the segment table which is used by */ /* Get the pointer to the segment table which is used by */
/* stab_initialize */ /* stab_initialize */
LOADADDR(r27, boot_cpuid) LOADADDR(r27, boot_cpuid)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/prom.h> #include <asm/prom.h>
...@@ -27,7 +28,7 @@ extern unsigned long reloc_offset(void); ...@@ -27,7 +28,7 @@ extern unsigned long reloc_offset(void);
static long lmb_add_region(struct lmb_region *, unsigned long, unsigned long, unsigned long); static long lmb_add_region(struct lmb_region *, unsigned long, unsigned long, unsigned long);
struct lmb lmb = { struct lmb lmb = {
0, 0, 0,
{0,0,0,0,{{0,0,0}}}, {0,0,0,0,{{0,0,0}}},
{0,0,0,0,{{0,0,0}}} {0,0,0,0,{{0,0,0}}}
}; };
...@@ -150,6 +151,10 @@ lmb_add(unsigned long base, unsigned long size) ...@@ -150,6 +151,10 @@ lmb_add(unsigned long base, unsigned long size)
struct lmb *_lmb = PTRRELOC(&lmb); struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_rgn = &(_lmb->memory); struct lmb_region *_rgn = &(_lmb->memory);
/* On pSeries LPAR systems, the first LMB is our RMO region. */
if ( base == 0 )
_lmb->rmo_size = size;
return lmb_add_region(_rgn, base, size, LMB_MEMORY_AREA); return lmb_add_region(_rgn, base, size, LMB_MEMORY_AREA);
} }
...@@ -257,12 +262,17 @@ lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long si ...@@ -257,12 +262,17 @@ lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long si
return (i < rgn->cnt) ? i : -1; return (i < rgn->cnt) ? i : -1;
} }
unsigned long unsigned long
lmb_alloc(unsigned long size, unsigned long align) lmb_alloc(unsigned long size, unsigned long align)
{
return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
}
unsigned long
lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
{ {
long i, j; long i, j;
unsigned long base; unsigned long base = 0;
unsigned long offset = reloc_offset(); unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb); struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_mem = &(_lmb->memory); struct lmb_region *_mem = &(_lmb->memory);
...@@ -276,7 +286,12 @@ lmb_alloc(unsigned long size, unsigned long align) ...@@ -276,7 +286,12 @@ lmb_alloc(unsigned long size, unsigned long align)
if ( lmbtype != LMB_MEMORY_AREA ) if ( lmbtype != LMB_MEMORY_AREA )
continue; continue;
if ( max_addr == LMB_ALLOC_ANYWHERE )
base = _ALIGN_DOWN(lmbbase+lmbsize-size, align); base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
else if ( lmbbase < max_addr )
base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
else
continue;
while ( (lmbbase <= base) && while ( (lmbbase <= base) &&
((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) { ((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) {
......
...@@ -619,8 +619,8 @@ prom_initialize_lmb(unsigned long mem) ...@@ -619,8 +619,8 @@ prom_initialize_lmb(unsigned long mem)
} }
static unsigned long __init static void __init
prom_instantiate_rtas(unsigned long mem) prom_instantiate_rtas(void)
{ {
unsigned long offset = reloc_offset(); unsigned long offset = reloc_offset();
struct prom_t *_prom = PTRRELOC(&prom); struct prom_t *_prom = PTRRELOC(&prom);
...@@ -653,16 +653,18 @@ prom_instantiate_rtas(unsigned long mem) ...@@ -653,16 +653,18 @@ prom_instantiate_rtas(unsigned long mem)
_rtas->size = getprop_rval; _rtas->size = getprop_rval;
prom_print(RELOC("instantiating rtas")); prom_print(RELOC("instantiating rtas"));
if (_rtas->size != 0) { if (_rtas->size != 0) {
/* unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
* Ask OF for some space for RTAS.
* Actually OF has bugs so we just arbitrarily /* Grab some space within the first RTAS_INSTANTIATE_MAX bytes
* use memory at the 6MB point. * of physical memory (or within the RMO region) because RTAS
* runs in 32-bit mode and relocate off.
*/ */
// The new code... if ( _naca->platform == PLATFORM_PSERIES_LPAR ) {
mem = PAGE_ALIGN(mem); struct lmb *_lmb = PTRRELOC(&lmb);
_rtas->base = mem + offset - KERNELBASE; rtas_region = min(_lmb->rmo_size, RTAS_INSTANTIATE_MAX);
}
_rtas->base = lmb_alloc_base(_rtas->size, PAGE_SIZE, rtas_region);
mem += _rtas->size;
prom_print(RELOC(" at 0x")); prom_print(RELOC(" at 0x"));
prom_print_hex(_rtas->base); prom_print_hex(_rtas->base);
...@@ -699,8 +701,6 @@ prom_instantiate_rtas(unsigned long mem) ...@@ -699,8 +701,6 @@ prom_instantiate_rtas(unsigned long mem)
#ifdef DEBUG_PROM #ifdef DEBUG_PROM
prom_print(RELOC("prom_instantiate_rtas: end...\n")); prom_print(RELOC("prom_instantiate_rtas: end...\n"));
#endif #endif
return mem;
} }
unsigned long prom_strtoul(const char *cp) unsigned long prom_strtoul(const char *cp)
...@@ -940,7 +940,7 @@ prom_initialize_tce_table(void) ...@@ -940,7 +940,7 @@ prom_initialize_tce_table(void)
align = (minalign < minsize) ? minsize : minalign; align = (minalign < minsize) ? minsize : minalign;
/* Carve out storage for the TCE table. */ /* Carve out storage for the TCE table. */
base = lmb_alloc(minsize, align); base = lmb_alloc(8UL << 20, 8UL << 20);
if ( !base ) { if ( !base ) {
prom_print(RELOC("ERROR, cannot find space for TCE table.\n")); prom_print(RELOC("ERROR, cannot find space for TCE table.\n"));
...@@ -1378,7 +1378,7 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, ...@@ -1378,7 +1378,7 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
mem = prom_bi_rec_reserve(mem); mem = prom_bi_rec_reserve(mem);
mem = prom_instantiate_rtas(mem); prom_instantiate_rtas();
/* Initialize some system info into the Naca early... */ /* Initialize some system info into the Naca early... */
mem = prom_initialize_naca(mem); mem = prom_initialize_naca(mem);
......
...@@ -28,6 +28,9 @@ union lmb_reg_property { ...@@ -28,6 +28,9 @@ union lmb_reg_property {
#define LMB_MEMORY_AREA 1 #define LMB_MEMORY_AREA 1
#define LMB_IO_AREA 2 #define LMB_IO_AREA 2
#define LMB_ALLOC_ANYWHERE 0
#define LMB_ALLOC_FIRST4GBYTE (1UL<<32)
struct lmb_property { struct lmb_property {
unsigned long base; unsigned long base;
unsigned long physbase; unsigned long physbase;
...@@ -45,6 +48,7 @@ struct lmb_region { ...@@ -45,6 +48,7 @@ struct lmb_region {
struct lmb { struct lmb {
unsigned long debug; unsigned long debug;
unsigned long rmo_size;
struct lmb_region memory; struct lmb_region memory;
struct lmb_region reserved; struct lmb_region reserved;
}; };
...@@ -59,6 +63,7 @@ extern long lmb_add_io(unsigned long base, unsigned long size); ...@@ -59,6 +63,7 @@ extern long lmb_add_io(unsigned long base, unsigned long size);
#endif /* CONFIG_MSCHUNKS */ #endif /* CONFIG_MSCHUNKS */
extern long lmb_reserve(unsigned long, unsigned long); extern long lmb_reserve(unsigned long, unsigned long);
extern unsigned long lmb_alloc(unsigned long, unsigned long); extern unsigned long lmb_alloc(unsigned long, unsigned long);
extern unsigned long lmb_alloc_base(unsigned long, unsigned long, unsigned long);
extern unsigned long lmb_phys_mem_size(void); extern unsigned long lmb_phys_mem_size(void);
extern unsigned long lmb_end_of_DRAM(void); extern unsigned long lmb_end_of_DRAM(void);
extern unsigned long lmb_abs_to_phys(unsigned long); extern unsigned long lmb_abs_to_phys(unsigned long);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
*/ */
#define RTAS_UNKNOWN_SERVICE (-1) #define RTAS_UNKNOWN_SERVICE (-1)
#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */
/* /*
* In general to call RTAS use rtas_token("string") to lookup * In general to call RTAS use rtas_token("string") to lookup
* an RTAS token for the given string (e.g. "event-scan"). * an RTAS token for the given string (e.g. "event-scan").
......
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