1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-11-17 11:18:26 +02:00
iris/mips/nanonote/nand-boot.ccp

163 lines
4.3 KiB
Plaintext
Raw Normal View History

2010-08-10 11:09:50 +03:00
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// mips/nanonote/nand-boot.ccp: standalone program for booting from nand.
// Copyright 2010 Bas Wijnen <wijnen@debian.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
asm volatile ("\t.set noreorder\n"
"\t.text\n"
"\t.globl __start\n"
"\t.globl addr_0\n"
"addr_0:\n"
2010-08-10 11:09:50 +03:00
"\t.word ~0\n"
"__start:\n"
"\tbal 1f\n"
"__hack_label:\n"
"\tnop\n"
"\t.word _gp\n"
"1:\n"
2010-08-22 23:03:06 +03:00
"\tori $t0, $zero, 0x0006\n"
"\tmtc0 $t0, $12\n"
2010-08-10 11:09:50 +03:00
"\tlw $gp, 0($ra)\n"
"\tla $sp, stack + 0x1000\n"
"\tla $t9, nandboot_start\n"
"\tjr $t9\n"
"\tnop\n"
"\t.fill 0x1b8 - (. - addr_0)\n"
"\t.word 0xd2b9e1a8\n" // Disk signature.
"\t.short 0x0000\n"
"\t.byte 0x00\n" // bootable: no.
"\t.byte 0x00, 0x02, 0x00\n" // first sector chs.
"\t.byte 0x83\n" // type.
"\t.byte 0x08, 0x18, 0x00\n" // last sector chs.
"\t.byte 0x01, 0x00, 0x00, 0x00\n" // first sector, lba.
"\t.byte 0xff, 0x01, 0x00, 0x00\n" // size, lba.
"\t.byte 0x00\n" // bootable: no.
"\t.byte 0x08, 0x19, 0x00\n" // first sector chs.
"\t.byte 0x83\n" // type.
"\t.byte 0x05, 0xe1, 0xf3\n" // last sector chs.
"\t.byte 0x00, 0x02, 0x00, 0x00\n" // first sector, lba: 256 kB.
"\t.byte 0x00, 0xfe, 0x1f, 0x00\n" // size, lba: 1 GB - first.
"\t.byte 0\n" // bootable: no.
"\t.byte 0, 0, 0\n" // first sector chs.
"\t.byte 0\n" // type.
"\t.byte 0, 0, 0\n" // last sector chs.
"\t.byte 0, 0, 0, 0\n" // first sector, lba.
"\t.byte 0, 0, 0, 0\n" // size, lba.
"\t.byte 0\n" // bootable: no.
"\t.byte 0, 0, 0\n" // first sector chs.
"\t.byte 0\n" // type.
"\t.byte 0, 0, 0\n" // last sector chs.
"\t.byte 0, 0, 0, 0\n" // first sector, lba.
"\t.byte 0, 0, 0, 0\n" // size, lba.
"\t.byte 0x55, 0xaa\n" // mbr signature.
2010-08-10 11:09:50 +03:00
"\t.set reorder")
#define __KERNEL__
#include <jz4740.hh>
2010-08-22 23:03:06 +03:00
#define DELAY()
static void debug (unsigned ch):
while !(UART0_LSR & UARTLSR_TDRQ):
UART0_TDR = ch
static void debug_num (unsigned num, unsigned base, unsigned min_digits = 1):
char const *encode = "0123456789abcdef"
unsigned digits = 1
unsigned power = 1
while power <= num / base || min_digits > digits:
power *= base
++digits
for unsigned i = 0; i < digits; ++i:
unsigned d = num / power
debug (encode[d])
num -= d * power
power /= base
static void debug (char const *f, ...):
unsigned *last = (unsigned *)&f
while *f:
if *f == '%':
++f
switch *f:
case '%':
debug ('%')
break
case 'd':
++last
debug_num (*last, 10)
break
case 'x':
++last
debug_num (*last, 0x10)
break
case 's':
++last
char *str = (char*)*last
while *str:
debug (*str++)
break
default:
debug ("warning: invalid character in dbg format string\n")
break
else:
debug (*f)
++f
#define debug_line() debug ("nand-boot line %d\n", __LINE__)
#include "nand.hh"
2010-08-10 11:09:50 +03:00
extern "C":
void nandboot_start ():
2010-08-22 23:03:06 +03:00
unsigned base = 0x18000000 + 0xa0000000
data = (volatile char *)base
command = (volatile char *)(base + 0x8000)
address = (volatile char *)(base + 0x10000)
pll_init ()
cpm_start_all ()
gpio_as_sdram_16bit ()
gpio_as_nand ()
setup_sdram ()
setup_uart ()
2010-08-10 11:09:50 +03:00
reset ()
// Load contents of nand flash (from 0x4000) into 0xa0600000;
unsigned a = 0x4000
unsigned target = 0xa0600000
while read (a, (char *)target):
a += 0x200
target += 0x200
2010-08-22 23:03:06 +03:00
// Tell about what'll happen.
debug ("Jumping to a0600000:\n")
for unsigned d = 0; d < 0x40; ++d:
debug (" ")
debug_num (((char *)0xa0600000)[d] & 0xff, 16, 2)
debug ('\n')
// Wait for the serial port to finish.
while !(UART0_LSR & UARTLSR_TEMT):
2010-08-10 11:09:50 +03:00
// Then jump to 0xa0600000.
2010-08-22 23:03:06 +03:00
((void (*)())0xa0600000) ()
2010-08-10 11:09:50 +03:00
unsigned char stack[0x1000]
unsigned __gxx_personality_v0