diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 29f7e4d4e..8b68f7b6b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -25,7 +25,7 @@ #define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 -#define GRUB_KERNEL_CPU_RAW_SIZE 0x100 +#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 #define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc #define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 7c59e761e..5e3fb7ad5 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -31,6 +31,7 @@ __start: _start: start: bal codestart +base: . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE compressed_size: .long 0 @@ -41,8 +42,69 @@ total_module_size: kernel_image_size: .long 0 codestart: - /* Decompress the payload. */ + /* Save our base. */ move $s0, $ra + + /* Parse arguments. Has to be done before relocation. + So need to do it in asm. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* $a2 has the environment. */ + move $t0, $a2 +argcont: + lw $t1, 0($t0) + beq $t1, $zero, argdone +#define DO_PARSE(str, reg) \ + addiu $t2, $s0, (str-base);\ + bal parsestr;\ + beq $v0, $zero, 1f;\ + move reg, $v0;\ + b 2f;\ +1: + DO_PARSE (busclockstr, $s2) + DO_PARSE (cpuclockstr, $s3) + DO_PARSE (memsizestr, $s4) + DO_PARSE (highmemsizestr, $s5) +2: + addiu $t0, $t0, 4 + b argcont +parsestr: + move $v0, $zero + move $t3, $t1 +3: + lb $t4, 0($t2) + lb $t5, 0($t3) + addiu $t2, $t2, 1 + addiu $t3, $t3, 1 + beq $t5, $zero, 1f + beq $t5, $t4, 3b + bne $t4, $zero, 1f + + addiu $t3, $t3, 0xffff +digcont: + lb $t5, 0($t3) + /* Substract '0' from digit. */ + addiu $t5, $t5, 0xffd0 + bltz $t5, 1f + addiu $t4, $t5, 0xfff7 + bgtz $t4, 1f + /* Multiply $v0 by 10 with bitshifts. */ + sll $v0, $v0, 1 + sll $t4, $v0, 2 + addu $v0, $v0, $t4 + addu $v0, $v0, $t5 + addiu $t3, $t3, 1 + b digcont +1: + jr $ra +busclockstr: .asciiz "busclock=" +cpuclockstr: .asciiz "cpuclock=" +memsizestr: .asciiz "memsize=" +highmemsizestr: .asciiz "highmemsize=" + .p2align 2 +argdone: +#endif + + /* Decompress the payload. */ addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) @@ -50,7 +112,8 @@ codestart: move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, - $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, $s1. + $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, + $s1, $s2, $s3, $s4 and $s5. On return $v0 contains uncompressed size. */ move $v0, $a2 @@ -84,9 +147,27 @@ VARIABLE(grub_prefix) */ . = _start + GRUB_KERNEL_CPU_DATA_END - +#ifdef GRUB_MACHINE_MIPS_YEELOONG +VARIABLE (grub_arch_busclock) + .long 0 +VARIABLE (grub_arch_cpuclock) + .long 0 +VARIABLE (grub_arch_memsize) + .long 0 +VARIABLE (grub_arch_highmemsize) + .long 0 +#endif cont: +#ifdef GRUB_MACHINE_MIPS_YEELOONG + lui $t1, %hi(grub_arch_busclock) + addiu $t1, %lo(grub_arch_busclock) + sw $s2, 0($t1) + sw $s3, 4($t1) + sw $s4, 8($t1) + sw $s5, 12($t1) +#endif + /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start)