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)
*/
/*
* We make as much of the exception code common between native Pseries
* and Iseries LPAR implementations as possible.
* We make as much of the exception code common between native
* exception handlers (including pSeries LPAR) and iSeries LPAR
* implementations as possible.
*/
/*
......@@ -1340,17 +1341,10 @@ _STATIC(__after_prom_start)
/* executed here. */
LOADADDR(r0, 4f) /* Jump to the copy of this code */
mtctr r0 /* that we just made */
mtctr r0 /* that we just made/relocated */
bctr
4: LOADADDR(r9,rtas)
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)
4: LOADADDR(r5,klimit)
sub r5,r5,r26
ld r5,0(r5) /* get the value of klimit */
sub r5,r5,r27
......@@ -1675,9 +1669,6 @@ _STATIC(start_here_pSeries)
addi r2,r2,0x4000
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 */
/* stab_initialize */
LOADADDR(r27, boot_cpuid)
......
......@@ -12,6 +12,7 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/types.h>
#include <asm/page.h>
#include <asm/prom.h>
......@@ -27,7 +28,7 @@ extern unsigned long reloc_offset(void);
static long lmb_add_region(struct lmb_region *, unsigned long, unsigned long, unsigned long);
struct lmb lmb = {
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)
struct lmb *_lmb = PTRRELOC(&lmb);
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);
}
......@@ -257,12 +262,17 @@ lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long si
return (i < rgn->cnt) ? i : -1;
}
unsigned long
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;
unsigned long base;
unsigned long base = 0;
unsigned long offset = reloc_offset();
struct lmb *_lmb = PTRRELOC(&lmb);
struct lmb_region *_mem = &(_lmb->memory);
......@@ -276,7 +286,12 @@ lmb_alloc(unsigned long size, unsigned long align)
if ( lmbtype != LMB_MEMORY_AREA )
continue;
if ( max_addr == LMB_ALLOC_ANYWHERE )
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) &&
((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) {
......
......@@ -619,8 +619,8 @@ prom_initialize_lmb(unsigned long mem)
}
static unsigned long __init
prom_instantiate_rtas(unsigned long mem)
static void __init
prom_instantiate_rtas(void)
{
unsigned long offset = reloc_offset();
struct prom_t *_prom = PTRRELOC(&prom);
......@@ -653,16 +653,18 @@ prom_instantiate_rtas(unsigned long mem)
_rtas->size = getprop_rval;
prom_print(RELOC("instantiating rtas"));
if (_rtas->size != 0) {
/*
* Ask OF for some space for RTAS.
* Actually OF has bugs so we just arbitrarily
* use memory at the 6MB point.
unsigned long rtas_region = RTAS_INSTANTIATE_MAX;
/* Grab some space within the first RTAS_INSTANTIATE_MAX bytes
* of physical memory (or within the RMO region) because RTAS
* runs in 32-bit mode and relocate off.
*/
// The new code...
mem = PAGE_ALIGN(mem);
_rtas->base = mem + offset - KERNELBASE;
if ( _naca->platform == PLATFORM_PSERIES_LPAR ) {
struct lmb *_lmb = PTRRELOC(&lmb);
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_hex(_rtas->base);
......@@ -699,8 +701,6 @@ prom_instantiate_rtas(unsigned long mem)
#ifdef DEBUG_PROM
prom_print(RELOC("prom_instantiate_rtas: end...\n"));
#endif
return mem;
}
unsigned long prom_strtoul(const char *cp)
......@@ -940,7 +940,7 @@ prom_initialize_tce_table(void)
align = (minalign < minsize) ? minsize : minalign;
/* Carve out storage for the TCE table. */
base = lmb_alloc(minsize, align);
base = lmb_alloc(8UL << 20, 8UL << 20);
if ( !base ) {
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,
mem = prom_bi_rec_reserve(mem);
mem = prom_instantiate_rtas(mem);
prom_instantiate_rtas();
/* Initialize some system info into the Naca early... */
mem = prom_initialize_naca(mem);
......
......@@ -28,6 +28,9 @@ union lmb_reg_property {
#define LMB_MEMORY_AREA 1
#define LMB_IO_AREA 2
#define LMB_ALLOC_ANYWHERE 0
#define LMB_ALLOC_FIRST4GBYTE (1UL<<32)
struct lmb_property {
unsigned long base;
unsigned long physbase;
......@@ -45,6 +48,7 @@ struct lmb_region {
struct lmb {
unsigned long debug;
unsigned long rmo_size;
struct lmb_region memory;
struct lmb_region reserved;
};
......@@ -59,6 +63,7 @@ extern long lmb_add_io(unsigned long base, unsigned long size);
#endif /* CONFIG_MSCHUNKS */
extern long lmb_reserve(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_end_of_DRAM(void);
extern unsigned long lmb_abs_to_phys(unsigned long);
......
......@@ -17,6 +17,8 @@
*/
#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
* 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