Commit d5313e0f authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Linus Torvalds

[PATCH] alpha: bootp fixes

- redefine "printk" as "srm_printk" for bootstrappers;
- fix stack corruption problem with bootp/bootpz loaders and older
  SRM consoles.
parent 99fcf73f
OUTPUT_FORMAT("elf64-alpha") OUTPUT_FORMAT("elf64-alpha")
ENTRY(__start) ENTRY(__start)
printk = srm_printk;
SECTIONS SECTIONS
{ {
. = 0x20000000; . = 0x20000000;
......
...@@ -26,6 +26,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr, ...@@ -26,6 +26,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long *vptb); unsigned long *vptb);
extern void move_stack(unsigned long new_stack);
struct hwrpb_struct *hwrpb = INIT_HWRPB; struct hwrpb_struct *hwrpb = INIT_HWRPB;
static struct pcb_struct pcb_va[1]; static struct pcb_struct pcb_va[1];
...@@ -118,12 +120,10 @@ static inline void ...@@ -118,12 +120,10 @@ static inline void
runkernel(void) runkernel(void)
{ {
__asm__ __volatile__( __asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$27\n\t" "bis %0,%0,$27\n\t"
"jmp ($27)" "jmp ($27)"
: /* no outputs: it doesn't even return */ : /* no outputs: it doesn't even return */
: "r" (START_ADDR), : "r" (START_ADDR));
"r" (PAGE_SIZE + INIT_STACK));
} }
extern char _end; extern char _end;
...@@ -147,9 +147,7 @@ start_kernel(void) ...@@ -147,9 +147,7 @@ start_kernel(void)
*/ */
static long nbytes; static long nbytes;
static char envval[256] __attribute__((aligned(8))); static char envval[256] __attribute__((aligned(8)));
#ifdef INITRD_IMAGE_SIZE
static unsigned long initrd_start; static unsigned long initrd_start;
#endif
srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n"); srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
if (INIT_HWRPB->pagesize != 8192) { if (INIT_HWRPB->pagesize != 8192) {
...@@ -164,13 +162,20 @@ start_kernel(void) ...@@ -164,13 +162,20 @@ start_kernel(void)
} }
pal_init(); pal_init();
#ifdef INITRD_IMAGE_SIZE
/* The initrd must be page-aligned. See below for the /* The initrd must be page-aligned. See below for the
cause of the magic number 5. */ cause of the magic number 5. */
initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1; initrd_start = ((START_ADDR + 5*KERNEL_SIZE + PAGE_SIZE) |
(PAGE_SIZE-1)) + 1;
#ifdef INITRD_IMAGE_SIZE
srm_printk("Initrd positioned at %#lx\n", initrd_start); srm_printk("Initrd positioned at %#lx\n", initrd_start);
#endif #endif
/*
* Move the stack to a safe place to ensure it won't be
* overwritten by kernel image.
*/
move_stack(initrd_start - PAGE_SIZE);
nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval)); nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
if (nbytes < 0 || nbytes >= sizeof(envval)) { if (nbytes < 0 || nbytes >= sizeof(envval)) {
nbytes = 0; nbytes = 0;
......
...@@ -41,9 +41,6 @@ ...@@ -41,9 +41,6 @@
#undef DEBUG_ADDRESSES #undef DEBUG_ADDRESSES
#undef DEBUG_LAST_STEPS #undef DEBUG_LAST_STEPS
#define DEBUG_SP(x) \
{register long sp asm("30"); srm_printk("%s (sp=%lx)\n", x, sp);}
extern unsigned long switch_to_osf_pal(unsigned long nr, extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long *vptb); unsigned long *vptb);
...@@ -51,6 +48,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr, ...@@ -51,6 +48,8 @@ extern unsigned long switch_to_osf_pal(unsigned long nr,
extern int decompress_kernel(void* destination, void *source, extern int decompress_kernel(void* destination, void *source,
size_t ksize, size_t kzsize); size_t ksize, size_t kzsize);
extern void move_stack(unsigned long new_stack);
struct hwrpb_struct *hwrpb = INIT_HWRPB; struct hwrpb_struct *hwrpb = INIT_HWRPB;
static struct pcb_struct pcb_va[1]; static struct pcb_struct pcb_va[1];
...@@ -163,12 +162,10 @@ static inline void ...@@ -163,12 +162,10 @@ static inline void
runkernel(void) runkernel(void)
{ {
__asm__ __volatile__( __asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$27\n\t" "bis %0,%0,$27\n\t"
"jmp ($27)" "jmp ($27)"
: /* no outputs: it doesn't even return */ : /* no outputs: it doesn't even return */
: "r" (START_ADDR), : "r" (START_ADDR));
"r" (PAGE_SIZE + INIT_STACK));
} }
/* Must record the SP (it is virtual) on entry, so we can make sure /* Must record the SP (it is virtual) on entry, so we can make sure
...@@ -253,7 +250,9 @@ extern char _end; ...@@ -253,7 +250,9 @@ extern char _end;
for "bootmem" anyway. for "bootmem" anyway.
*/ */
#define K_COPY_IMAGE_START NEXT_PAGE(K_KERNEL_IMAGE_END) #define K_COPY_IMAGE_START NEXT_PAGE(K_KERNEL_IMAGE_END)
#define K_INITRD_START NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE) /* Reserve one page below INITRD for the new stack. */
#define K_INITRD_START \
NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE + PAGE_SIZE)
#define K_COPY_IMAGE_END \ #define K_COPY_IMAGE_END \
(K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE) (K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE)
#define K_COPY_IMAGE_SIZE \ #define K_COPY_IMAGE_SIZE \
...@@ -419,8 +418,7 @@ start_kernel(void) ...@@ -419,8 +418,7 @@ start_kernel(void)
initrd_image_start, initrd_image_start,
INITRD_IMAGE_SIZE); INITRD_IMAGE_SIZE);
#endif #endif
memcpy((void *)initrd_image_start, memcpy((void *)initrd_image_start, (void *)V_INITRD_START,
(void *)V_INITRD_START,
INITRD_IMAGE_SIZE); INITRD_IMAGE_SIZE);
#endif /* INITRD_IMAGE_SIZE */ #endif /* INITRD_IMAGE_SIZE */
...@@ -436,9 +434,14 @@ start_kernel(void) ...@@ -436,9 +434,14 @@ start_kernel(void)
K_KERNEL_IMAGE_START, K_KERNEL_IMAGE_START,
(unsigned)KERNEL_SIZE); (unsigned)KERNEL_SIZE);
#endif #endif
/*
* Move the stack to a safe place to ensure it won't be
* overwritten by kernel image.
*/
move_stack(initrd_image_start - PAGE_SIZE);
memcpy((void *)K_KERNEL_IMAGE_START, memcpy((void *)K_KERNEL_IMAGE_START,
(void *)uncompressed_image_start, (void *)uncompressed_image_start, KERNEL_SIZE);
KERNEL_SIZE);
} }
/* Clear the zero page, then move the argument list in. */ /* Clear the zero page, then move the argument list in. */
......
...@@ -100,3 +100,24 @@ halt: ...@@ -100,3 +100,24 @@ halt:
.prologue 0 .prologue 0
call_pal PAL_halt call_pal PAL_halt
.end halt .end halt
/* $16 - new stack page */
.align 3
.globl move_stack
.ent move_stack
move_stack:
.prologue 0
lda $0, 0x1fff($31)
and $0, $30, $1 /* Stack offset */
or $1, $16, $16 /* New stack pointer */
mov $30, $1
mov $16, $2
1: ldq $3, 0($1) /* Move the stack */
addq $1, 8, $1
stq $3, 0($2)
and $0, $1, $4
addq $2, 8, $2
bne $4, 1b
mov $16, $30
ret ($26)
.end move_stack
...@@ -205,15 +205,3 @@ decompress_kernel(void *output_start, ...@@ -205,15 +205,3 @@ decompress_kernel(void *output_start,
/* puts(" done, booting the kernel.\n"); */ /* puts(" done, booting the kernel.\n"); */
return output_ptr; return output_ptr;
} }
/* dummy-up printk */
asmlinkage int printk(const char *fmt, ...)
{
va_list args;
long ret;
va_start(args, fmt);
ret = srm_printk(fmt, args);
va_end(args);
return ret;
}
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