mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-04 22:54:03 +02:00
163 lines
4.3 KiB
COBOL
163 lines
4.3 KiB
COBOL
#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"
|
|
"\t.word ~0\n"
|
|
"__start:\n"
|
|
"\tbal 1f\n"
|
|
"__hack_label:\n"
|
|
"\tnop\n"
|
|
"\t.word _gp\n"
|
|
"1:\n"
|
|
"\tori $t0, $zero, 0x0006\n"
|
|
"\tmtc0 $t0, $12\n"
|
|
"\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.
|
|
|
|
"\t.set reorder")
|
|
|
|
#define __KERNEL__
|
|
#include <jz4740.hh>
|
|
|
|
#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"
|
|
|
|
extern "C":
|
|
void nandboot_start ():
|
|
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 ()
|
|
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
|
|
// 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):
|
|
// Then jump to 0xa0600000.
|
|
((void (*)())0xa0600000) ()
|
|
|
|
unsigned char stack[0x1000]
|
|
|
|
unsigned __gxx_personality_v0
|