Root/mips/nanonote/nand-boot.ccp

1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// mips/nanonote/nand-boot.ccp: standalone program for booting from nand.
4// Copyright 2010 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19asm volatile ("\t.set noreorder\n"
20    "\t.text\n"
21    "\t.globl __start\n"
22    "\t.globl addr_0\n"
23    "addr_0:\n"
24    "\t.word ~0\n"
25    "__start:\n"
26    "\tbal 1f\n"
27    "__hack_label:\n"
28    "\tnop\n"
29    "\t.word _gp\n"
30    "1:\n"
31    "\tori $t0, $zero, 0x0006\n"
32    "\tmtc0 $t0, $12\n"
33    "\tlw $gp, 0($ra)\n"
34    "\tla $sp, stack + 0x1000\n"
35    "\tla $t9, nandboot_start\n"
36    "\tjr $t9\n"
37    "\tnop\n"
38    "\t.fill 0x1b8 - (. - addr_0)\n"
39    "\t.word 0xd2b9e1a8\n" // Disk signature.
40    "\t.short 0x0000\n"
41
42    "\t.byte 0x00\n" // bootable: no.
43    "\t.byte 0x00, 0x02, 0x00\n" // first sector chs.
44    "\t.byte 0x83\n" // type.
45    "\t.byte 0x08, 0x18, 0x00\n" // last sector chs.
46    "\t.byte 0x01, 0x00, 0x00, 0x00\n" // first sector, lba.
47    "\t.byte 0xff, 0x01, 0x00, 0x00\n" // size, lba.
48
49    "\t.byte 0x00\n" // bootable: no.
50    "\t.byte 0x08, 0x19, 0x00\n" // first sector chs.
51    "\t.byte 0x83\n" // type.
52    "\t.byte 0x05, 0xe1, 0xf3\n" // last sector chs.
53    "\t.byte 0x00, 0x02, 0x00, 0x00\n" // first sector, lba: 256 kB.
54    "\t.byte 0x00, 0xfe, 0x1f, 0x00\n" // size, lba: 1 GB - first.
55
56    "\t.byte 0\n" // bootable: no.
57    "\t.byte 0, 0, 0\n" // first sector chs.
58    "\t.byte 0\n" // type.
59    "\t.byte 0, 0, 0\n" // last sector chs.
60    "\t.byte 0, 0, 0, 0\n" // first sector, lba.
61    "\t.byte 0, 0, 0, 0\n" // size, lba.
62
63    "\t.byte 0\n" // bootable: no.
64    "\t.byte 0, 0, 0\n" // first sector chs.
65    "\t.byte 0\n" // type.
66    "\t.byte 0, 0, 0\n" // last sector chs.
67    "\t.byte 0, 0, 0, 0\n" // first sector, lba.
68    "\t.byte 0, 0, 0, 0\n" // size, lba.
69
70    "\t.byte 0x55, 0xaa\n" // mbr signature.
71
72    "\t.set reorder")
73
74#define __KERNEL__
75#include <jz4740.hh>
76
77#define DELAY()
78
79static void debug (unsigned ch):
80    while !(UART0_LSR & UARTLSR_TDRQ):
81    UART0_TDR = ch
82
83static void debug_num (unsigned num, unsigned base, unsigned min_digits = 1):
84    char const *encode = "0123456789abcdef"
85    unsigned digits = 1
86    unsigned power = 1
87    while power <= num / base || min_digits > digits:
88        power *= base
89        ++digits
90    for unsigned i = 0; i < digits; ++i:
91        unsigned d = num / power
92        debug (encode[d])
93        num -= d * power
94        power /= base
95
96static void debug (char const *f, ...):
97    unsigned *last = (unsigned *)&f
98    while *f:
99        if *f == '%':
100            ++f
101            switch *f:
102                case '%':
103                    debug ('%')
104                    break
105                case 'd':
106                    ++last
107                    debug_num (*last, 10)
108                    break
109                case 'x':
110                    ++last
111                    debug_num (*last, 0x10)
112                    break
113                case 's':
114                    ++last
115                    char *str = (char*)*last
116                    while *str:
117                        debug (*str++)
118                    break
119                default:
120                    debug ("warning: invalid character in dbg format string\n")
121                    break
122        else:
123            debug (*f)
124        ++f
125
126#define debug_line() debug ("nand-boot line %d\n", __LINE__)
127
128#include "nand.hh"
129
130extern "C":
131    void nandboot_start ():
132        unsigned base = 0x18000000 + 0xa0000000
133        data = (volatile char *)base
134        command = (volatile char *)(base + 0x8000)
135        address = (volatile char *)(base + 0x10000)
136        pll_init ()
137        cpm_start_all ()
138        gpio_as_sdram_16bit ()
139        gpio_as_nand ()
140        setup_sdram ()
141        setup_uart (true)
142        reset ()
143        // Load contents of nand flash (from 0x4000) into 0xa0600000;
144        unsigned a = 0x4000
145        unsigned target = 0xa0600000
146        while read (a, (char *)target):
147            a += 0x200
148            target += 0x200
149        // Tell about what'll happen.
150        debug ("Jumping to a0600000:\n")
151        for unsigned d = 0; d < 0x40; ++d:
152            debug (" ")
153            debug_num (((char *)0xa0600000)[d] & 0xff, 16, 2)
154        debug ('\n')
155        // Wait for the serial port to finish.
156        while !(UART0_LSR & UARTLSR_TEMT):
157        // Then jump to 0xa0600000.
158        ((void (*)())0xa0600000) ()
159
160unsigned char stack[0x1000]
161
162unsigned __gxx_personality_v0
163

Archive Download this file

Branches:
master



interactive