| init.config |
| 1 | 1 | # driver <name> = '<filename>' load a file into memory to be run priviledged. |
| 2 | 2 | # program <name> = '<filename>' load a file into memory to be run normally. |
| 3 | | driver driver_lcd = "lcd.elf" |
| 4 | | driver driver_buzzer = "buzzer.elf" |
| 3 | #driver driver_lcd = "lcd.elf" |
| 4 | #driver driver_buzzer = "buzzer.elf" |
| 5 | 5 | driver driver_gpio = "gpio.elf" |
| 6 | | program alarm = "alarm.elf" |
| 7 | | program gui = "gui.elf" |
| 6 | #program alarm = "alarm.elf" |
| 7 | #program gui = "gui.elf" |
| 8 | 8 | driver nand = "nand.elf" |
| 9 | | driver sdmmc = "sd+mmc.elf" |
| 10 | | program partition = "partition.elf" |
| 11 | | program fat = "fat.elf" |
| 12 | | program test = "test.elf" |
| 9 | #driver sdmmc = "sd+mmc.elf" |
| 10 | #program partition = "partition.elf" |
| 11 | #program fat = "fat.elf" |
| 12 | #program test = "test.elf" |
| 13 | #driver rtc = "rtc.elf" |
| 13 | 14 | |
| 14 | 15 | # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program. |
| 15 | | receive driver_lcd / Display = display |
| 16 | | receive driver_lcd / Setting = display_bright |
| 17 | | receive driver_buzzer / Buzzer = buzzer |
| 16 | #receive driver_lcd / Display = display |
| 17 | #receive driver_lcd / Setting = display_bright |
| 18 | #receive driver_buzzer / Buzzer = buzzer |
| 18 | 19 | receive driver_gpio / Keyboard , 0 = keyboard |
| 19 | 20 | receive driver_gpio / Keyboard , 1 = sysreq |
| 20 | 21 | receive driver_gpio / Event = sdmmc_gpio |
| 21 | | receive alarm / UI = ui |
| 22 | | receive sdmmc / WString = sdmmc |
| 23 | | receive partition / WString, 0 = p0 |
| 24 | | receive partition / WString, 1 = p1 |
| 25 | | receive partition / WString, 2 = p2 |
| 26 | | receive partition / WString, 3 = p3 |
| 27 | | receive fat / Directory = root |
| 22 | #receive alarm / UI = ui |
| 23 | #receive sdmmc / WString = sdmmc |
| 24 | #receive partition / WString, 0 = p0 |
| 25 | #receive partition / WString, 1 = p1 |
| 26 | #receive partition / WString, 2 = p2 |
| 27 | #receive partition / WString, 3 = p3 |
| 28 | #receive fat / Directory = root |
| 28 | 29 | |
| 29 | 30 | # sysreq <cap> use a capability as the system request keyboard. |
| 30 | 31 | sysreq sysreq |
| 31 | 32 | |
| 32 | 33 | # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it. |
| 33 | | give gui / UI = ui |
| 34 | | give gui / Display = display |
| 35 | | give gui / Setting = display_bright |
| 36 | | give gui / Buzzer = buzzer |
| 37 | | give gui / Keyboard = keyboard |
| 38 | | give sdmmc / Event = sdmmc_gpio |
| 39 | | give partition / WString = sdmmc |
| 40 | | give fat / WString = p0 |
| 41 | | give test / Directory = root |
| 34 | #give gui / UI = ui |
| 35 | #give gui / Display = display |
| 36 | #give gui / Setting = display_bright |
| 37 | #give gui / Buzzer = buzzer |
| 38 | #give gui / Keyboard = keyboard |
| 39 | #give sdmmc / Event = sdmmc_gpio |
| 40 | #give partition / WString = sdmmc |
| 41 | #give fat / WString = p0 |
| 42 | #give test / Directory = root |
| 42 | 43 | |
| 43 | 44 | # include <file> include a file as another config file. |
| 44 | 45 | |
| mips/nanonote/Makefile.arch |
| 17 | 17 | |
| 18 | 18 | start_load = 0xa0600000 |
| 19 | 19 | load = 0x80000000 |
| 20 | | #UDC_BOOT = comment this out for nand boot |
| 20 | UDC_BOOT = comment this out for nand boot |
| 21 | |
| 22 | ifdef UDC_BOOT |
| 23 | boot_threads = $(standard_boot_programs) $(udc_boot_programs) |
| 24 | threadlist = mips/nanonote/threadlist-udc |
| 25 | ARCH_CXXFLAGS = -DNUM_THREADS=2 |
| 26 | all: mips/nanonote/nand-boot.raw test |
| 27 | else |
| 28 | boot_threads = $(standard_boot_programs) $(sd_boot_programs) |
| 29 | threadlist = mips/nanonote/threadlist-sd |
| 30 | ARCH_CXXFLAGS = -DNUM_THREADS=4 |
| 31 | all: mips/nanonote/nand-boot.raw iris-sd.tar |
| 32 | iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config |
| 33 | mkimage -A mips -T kernel -a $(start_load) -e a$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b2-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g' |
| 34 | cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference |
| 35 | endif |
| 21 | 36 | |
| 22 | 37 | ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL |
| 23 | 38 | CROSS = mipsel-linux-gnu- |
| ... | ... | |
| 26 | 41 | OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) |
| 27 | 42 | iris.elf: LDFLAGS = --omagic -Ttext $(load) |
| 28 | 43 | mips/start.elf: LDFLAGS = --omagic -Ttext $(start_load) |
| 44 | mips/nanonote/nand-boot.elf: LDFLAGS = --omagic -Ttext 0x80000000 |
| 45 | |
| 46 | source/nand.o: mips/nanonote/nand-boot.raw |
| 29 | 47 | |
| 30 | 48 | arch_iris_sources = mips/interrupts.cc mips/arch.cc |
| 31 | 49 | boot_sources = mips/init.cc mips/nanonote/board.cc |
| ... | ... | |
| 34 | 52 | sd_boot_programs = sd+mmc partition fat |
| 35 | 53 | standard_boot_programs = bootinit |
| 36 | 54 | |
| 37 | | programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs) |
| 38 | | |
| 39 | | ifdef UDC_BOOT |
| 40 | | boot_threads = $(standard_boot_programs) $(udc_boot_programs) |
| 41 | | threadlist = mips/nanonote/threadlist-udc |
| 42 | | ARCH_CXXFLAGS = -DNUM_THREADS=2 |
| 43 | | all: test |
| 44 | | else |
| 45 | | boot_threads = $(standard_boot_programs) $(sd_boot_programs) |
| 46 | | threadlist = mips/nanonote/threadlist-sd |
| 47 | | ARCH_CXXFLAGS = -DNUM_THREADS=4 |
| 48 | | all: iris-sd.tar |
| 49 | | iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config |
| 50 | | mkimage -A mips -T kernel -a $(start_load) -e a$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b2-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g' |
| 51 | | cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference |
| 52 | | endif |
| 55 | programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs) |
| 53 | 56 | |
| 54 | 57 | mips/start.o:mips/start.S Makefile Makefile.arch iris.raw |
| 55 | 58 | $(CC) $(CPPFLAGS) -DSTART=0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8') -c $< -o $@ |
| 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 | |
| 19 | // The following defines are taken from mtd/nand.h in the Linux source. |
| 20 | |
| 21 | asm volatile ("\t.set noreorder\n" |
| 22 | "\t.text\n" |
| 23 | "\t.globl __start\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 | "\tlw $gp, 0($ra)\n" |
| 32 | "\tla $sp, stack + 0x1000\n" |
| 33 | "\tla $t9, nandboot_start\n" |
| 34 | "\tjr $t9\n" |
| 35 | "\tnop\n" |
| 36 | "\t.set reorder") |
| 37 | |
| 38 | #define __KERNEL__ |
| 39 | #include <jz4740.hh> |
| 40 | |
| 41 | // Standard NAND flash commands |
| 42 | #define CMD_READ0 0 |
| 43 | #define CMD_READ1 1 |
| 44 | #define CMD_RNDOUT 5 |
| 45 | #define CMD_PAGEPROG 0x10 |
| 46 | #define CMD_READOOB 0x50 |
| 47 | #define CMD_ERASE1 0x60 |
| 48 | #define CMD_STATUS 0x70 |
| 49 | #define CMD_STATUS_MULTI 0x71 |
| 50 | #define CMD_SEQIN 0x80 |
| 51 | #define CMD_RNDIN 0x85 |
| 52 | #define CMD_READID 0x90 |
| 53 | #define CMD_ERASE2 0xd0 |
| 54 | #define CMD_RESET 0xff |
| 55 | |
| 56 | // Extended commands for large page devices |
| 57 | #define CMD_READSTART 0x30 |
| 58 | #define CMD_RNDOUTSTART 0xE0 |
| 59 | #define CMD_CACHEDPROG 0x15 |
| 60 | |
| 61 | // Status bits |
| 62 | #define STATUS_FAIL 0x01 |
| 63 | #define STATUS_FAIL_N1 0x02 |
| 64 | #define STATUS_TRUE_READY 0x20 |
| 65 | #define STATUS_READY 0x40 |
| 66 | #define STATUS_WP 0x80 |
| 67 | |
| 68 | static volatile char *command |
| 69 | static volatile char *address |
| 70 | static volatile char *data |
| 71 | |
| 72 | static unsigned page_bits |
| 73 | static unsigned redundant_bits |
| 74 | static unsigned block_bits |
| 75 | static unsigned word_size |
| 76 | |
| 77 | static void unbusy (): |
| 78 | while !(gpio_get_port (2) & (1 << 30)): |
| 79 | // Do nothing. |
| 80 | // Delay. |
| 81 | for unsigned i = 0; i < 1000; ++i: |
| 82 | gpio_set (0, 0) |
| 83 | |
| 84 | static void addr (unsigned d): |
| 85 | unbusy () |
| 86 | *address = d |
| 87 | unbusy () |
| 88 | |
| 89 | static void cmd (unsigned d): |
| 90 | unbusy () |
| 91 | *command = d |
| 92 | unbusy () |
| 93 | |
| 94 | static void wdata (unsigned d): |
| 95 | unbusy () |
| 96 | *data = d |
| 97 | unbusy () |
| 98 | |
| 99 | static unsigned rdata (): |
| 100 | unbusy () |
| 101 | unsigned ret = *data |
| 102 | unbusy () |
| 103 | return ret |
| 104 | |
| 105 | // Reset nand controller. |
| 106 | static void reset (): |
| 107 | unsigned base = 0xa0000000 + 0x18000000 |
| 108 | data = (volatile char *)base |
| 109 | command = (volatile char *)(base + 0x8000) |
| 110 | address = (volatile char *)(base + 0x10000) |
| 111 | |
| 112 | // Set up. |
| 113 | gpio_as_nand () |
| 114 | EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1 |
| 115 | |
| 116 | // Reset nand. |
| 117 | cmd (CMD_RESET) |
| 118 | |
| 119 | cmd (CMD_READID) |
| 120 | addr (0) |
| 121 | unsigned d = rdata () |
| 122 | //unsigned maker = d |
| 123 | d = rdata () |
| 124 | //unsigned device = d |
| 125 | d = rdata () |
| 126 | //unsigned internal_chip_number = 1 << (d & 0x3) |
| 127 | //unsigned cell_type = 2 << ((d >> 2) & 0x3) |
| 128 | //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3) |
| 129 | //bool can_interleave_program_between_chips = d & 0x40 |
| 130 | //bool can_cache_program = d & 0x80 |
| 131 | d = rdata () |
| 132 | page_bits = 10 + (d & 3) |
| 133 | redundant_bits = (d & 4 ? 4 : 3) |
| 134 | block_bits = 16 + ((d >> 4) & 3) |
| 135 | word_size = (d & 0x40 ? 16 : 8) |
| 136 | //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50) |
| 137 | d = rdata () |
| 138 | //unsigned num_planes = 1 << ((d >> 2) & 3) |
| 139 | //unsigned plane_bits = 26 + ((d >> 4) & 7) |
| 140 | |
| 141 | // Read 512 bytes from nand and store them into buffer. a must be aligned. |
| 142 | // Return value is true if the oob claims there is valid data. |
| 143 | static bool read (unsigned a, char *buffer): |
| 144 | unsigned column = a & ((1 << page_bits) - 1) |
| 145 | unsigned row = a >> page_bits |
| 146 | cmd (CMD_READ0) |
| 147 | addr (column) |
| 148 | addr (column >> 8) |
| 149 | addr (row) |
| 150 | addr (row >> 8) |
| 151 | addr (row >> 16) |
| 152 | cmd (CMD_READSTART) |
| 153 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST |
| 154 | for unsigned t = 0; t < 0x200; ++t: |
| 155 | buffer[t] = rdata () |
| 156 | EMC_NFECR = EMC_NFECR_RS | EMC_NFECR_RS_DECODING |
| 157 | char error[9] |
| 158 | // Spare space (starts at 1 << page_bits) |
| 159 | // 0: unused |
| 160 | // 2: detect valid data (at least 1 byte == 0 means valid) |
| 161 | // 5: unused |
| 162 | // 6: 9-byte ecc of 1st 512 bytes |
| 163 | // 15: 9-byte ecc of 2nd 512 bytes |
| 164 | // 24: 9-byte ecc of 3rd 512 bytes |
| 165 | // 33: 9-byte ecc of 4th 512 bytes |
| 166 | // 42: unused |
| 167 | // 64: end of space |
| 168 | unsigned validcol = (1 << page_bits) + 2 |
| 169 | bool valid = false |
| 170 | cmd (CMD_RNDOUT) |
| 171 | addr (validcol) |
| 172 | addr (validcol >> 8) |
| 173 | cmd (CMD_RNDOUTSTART) |
| 174 | for unsigned t = 0; t < 3; ++t: |
| 175 | valid = rdata () == 0 || valid |
| 176 | unsigned errcol = (1 << page_bits) + (column >> 9) * 9 + 6 |
| 177 | cmd (CMD_RNDOUT) |
| 178 | addr (errcol) |
| 179 | addr (errcol >> 8) |
| 180 | cmd (CMD_RNDOUTSTART) |
| 181 | for unsigned t = 0; t < 9; ++t: |
| 182 | error[t] = rdata () |
| 183 | EMC_NFPAR (0) = ((unsigned *)error)[0] |
| 184 | EMC_NFPAR (1) = ((unsigned *)error)[1] |
| 185 | EMC_NFPAR (2) = error[9] |
| 186 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY |
| 187 | while !(EMC_NFINTS & EMC_NFINTS_DECF): |
| 188 | // Do nothing. |
| 189 | unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT |
| 190 | for unsigned i = 0; i < errs; ++i: |
| 191 | buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff |
| 192 | |
| 193 | extern "C": |
| 194 | void nandboot_start (): |
| 195 | reset () |
| 196 | // Load contents of nand flash (from 0x4000) into 0xa0600000; |
| 197 | unsigned a = 0x4000 |
| 198 | unsigned target = 0xa0600000 |
| 199 | while read (a, (char *)target): |
| 200 | a += 0x200 |
| 201 | target += 0x200 |
| 202 | // Then jump to 0xa0600000. |
| 203 | return ((void (*)())0xa0600000) () |
| 204 | |
| 205 | unsigned char stack[0x1000] |
| 206 | |
| 207 | unsigned __gxx_personality_v0 |
| source/nand.ccp |
| 24 | 24 | |
| 25 | 25 | // Standard NAND flash commands |
| 26 | 26 | #define CMD_READ0 0 |
| 27 | | #define CMD_READ1 1 |
| 28 | | #define CMD_RNDOUT 5 |
| 27 | #define CMD_READSTART 0x30 |
| 28 | |
| 29 | #define CMD_READID 0x90 |
| 30 | |
| 31 | #define CMD_RESET 0xff |
| 32 | |
| 33 | #define CMD_SEQIN 0x80 |
| 29 | 34 | #define CMD_PAGEPROG 0x10 |
| 30 | | #define CMD_READOOB 0x50 |
| 35 | |
| 31 | 36 | #define CMD_ERASE1 0x60 |
| 32 | | #define CMD_STATUS 0x70 |
| 33 | | #define CMD_STATUS_MULTI 0x71 |
| 34 | | #define CMD_SEQIN 0x80 |
| 35 | | #define CMD_RNDIN 0x85 |
| 36 | | #define CMD_READID 0x90 |
| 37 | 37 | #define CMD_ERASE2 0xd0 |
| 38 | | #define CMD_RESET 0xff |
| 39 | 38 | |
| 40 | | // Extended commands for large page devices |
| 41 | | #define CMD_READSTART 0x30 |
| 39 | #define CMD_RNDIN 0x85 |
| 40 | |
| 41 | #define CMD_RNDOUT 5 |
| 42 | 42 | #define CMD_RNDOUTSTART 0xE0 |
| 43 | | #define CMD_CACHEDPROG 0x15 |
| 44 | | |
| 45 | | // Extended commands for AG-AND device |
| 46 | | // Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but |
| 47 | | // there is no way to distinguish that from NAND_CMD_READ0 |
| 48 | | // until the remaining sequence of commands has been completed |
| 49 | | // so add a high order bit and mask it off in the command. |
| 50 | | #define CMD_DEPLETE1 0x100 |
| 51 | | #define CMD_DEPLETE2 0x38 |
| 52 | | #define CMD_STATUS_MULTI 0x71 |
| 53 | | #define CMD_STATUS_ERROR 0x72 |
| 54 | | // multi-bank error status (banks 0-3) |
| 55 | | #define CMD_STATUS_ERROR0 0x73 |
| 56 | | #define CMD_STATUS_ERROR1 0x74 |
| 57 | | #define CMD_STATUS_ERROR2 0x75 |
| 58 | | #define CMD_STATUS_ERROR3 0x76 |
| 59 | | #define CMD_STATUS_RESET 0x7f |
| 60 | | #define CMD_STATUS_CLEAR 0xff |
| 61 | | |
| 62 | | #define CMD_NONE -1 |
| 43 | |
| 44 | #define CMD_STATUS 0x70 |
| 63 | 45 | |
| 64 | 46 | // Status bits |
| 65 | 47 | #define STATUS_FAIL 0x01 |
| 66 | | #define STATUS_FAIL_N1 0x02 |
| 67 | | #define STATUS_TRUE_READY 0x20 |
| 68 | 48 | #define STATUS_READY 0x40 |
| 69 | | #define STATUS_WP 0x80 |
| 49 | #define STATUS_WRITABLE 0x80 |
| 70 | 50 | |
| 71 | 51 | static volatile char *command |
| 72 | 52 | static volatile char *address |
| ... | ... | |
| 154 | 134 | //unsigned num_planes = 1 << ((d >> 2) & 3) |
| 155 | 135 | //unsigned plane_bits = 26 + ((d >> 4) & 7) |
| 156 | 136 | |
| 157 | | static void read (unsigned a, char *buffer): |
| 137 | static bool read (unsigned a, char *buffer): |
| 158 | 138 | unsigned column = a & ((1 << page_bits) - 1) |
| 159 | 139 | unsigned row = a >> page_bits |
| 160 | 140 | //Iris::debug ("reading: %x/%x/%x: ", a, row, column) |
| 161 | | cmd (CMD_READ0) |
| 162 | | addr (column) |
| 163 | | addr (column >> 8) |
| 164 | | addr (row) |
| 165 | | addr (row >> 8) |
| 166 | | addr (row >> 16) |
| 167 | | cmd (CMD_READSTART) |
| 168 | | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST |
| 169 | | for unsigned t = 0; t < 0x200; ++t: |
| 170 | | buffer[t] = rdata () |
| 171 | | char error[9] |
| 141 | // Read oob information first. |
| 142 | char error[12] |
| 172 | 143 | // Spare space (starts at 1 << page_bits) |
| 173 | 144 | // 0: unused |
| 174 | 145 | // 2: detect valid data (at least 1 byte == 0 means valid) |
| ... | ... | |
| 179 | 150 | // 33: 9-byte ecc of 4th 512 bytes |
| 180 | 151 | // 42: unused |
| 181 | 152 | // 64: end of space |
| 182 | | unsigned errcol = (1 << page_bits) + (column >> 9) * 9 + 6 |
| 153 | unsigned col = (1 << page_bits) + 2 |
| 154 | cmd (CMD_READ0) |
| 155 | addr (col) |
| 156 | addr (col >> 8) |
| 157 | addr (row) |
| 158 | addr (row >> 8) |
| 159 | addr (row >> 16) |
| 160 | cmd (CMD_READSTART) |
| 161 | bool valid = false |
| 162 | for unsigned t = 0; t < 3; ++t: |
| 163 | if rdata () == 0: |
| 164 | valid = true |
| 165 | break |
| 166 | if !valid: |
| 167 | return false |
| 168 | col = (1 << page_bits) + 6 + 9 * (column >> 9) |
| 183 | 169 | cmd (CMD_RNDOUT) |
| 184 | | addr (errcol) |
| 185 | | addr (errcol >> 8) |
| 170 | addr (col) |
| 171 | addr (col >> 8) |
| 186 | 172 | cmd (CMD_RNDOUTSTART) |
| 187 | 173 | for unsigned t = 0; t < 9; ++t: |
| 188 | 174 | error[t] = rdata () |
| 175 | cmd (CMD_RNDOUT) |
| 176 | addr (column) |
| 177 | addr (column >> 8) |
| 178 | cmd (CMD_RNDOUTSTART) |
| 179 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST |
| 180 | for unsigned t = 0; t < 0x200; ++t: |
| 181 | buffer[t] = rdata () |
| 189 | 182 | EMC_NFPAR (0) = ((unsigned *)error)[0] |
| 190 | 183 | EMC_NFPAR (1) = ((unsigned *)error)[1] |
| 191 | 184 | EMC_NFPAR (2) = error[9] |
| ... | ... | |
| 198 | 191 | buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff |
| 199 | 192 | |
| 200 | 193 | static void write (unsigned a, char *buffer): |
| 194 | kdebug_line () |
| 201 | 195 | unsigned row = a >> page_bits |
| 196 | kdebug_line () |
| 202 | 197 | //Iris::debug ("writing: %x/%x: ", a, row) |
| 203 | 198 | cmd (CMD_SEQIN) |
| 199 | kdebug_line () |
| 204 | 200 | addr (0) |
| 201 | kdebug_line () |
| 205 | 202 | addr (0) |
| 203 | kdebug_line () |
| 206 | 204 | addr (row) |
| 205 | kdebug_line () |
| 207 | 206 | addr (row >> 8) |
| 207 | kdebug_line () |
| 208 | 208 | addr (row >> 16) |
| 209 | | char ecc[4][9] |
| 209 | kdebug_line () |
| 210 | char ecc[4][12] |
| 210 | 211 | for unsigned i = 0; i < 0x4; ++i: |
| 212 | kdebug_line () |
| 211 | 213 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING | EMC_NFECR_ERST |
| 214 | Iris::debug ("writing data from %x\n", (unsigned)buffer + i * 0x200) |
| 212 | 215 | for unsigned j = 0; j < 0x200; ++j: |
| 213 | 216 | wdata (buffer[i * 0x200 + j]) |
| 217 | kdebug_line () |
| 214 | 218 | while !(EMC_NFINTS & EMC_NFINTS_ENCF): |
| 215 | 219 | Iris::schedule () |
| 220 | kdebug_line () |
| 216 | 221 | ((unsigned *)ecc[i])[0] = EMC_NFPAR (0) |
| 222 | kdebug_line () |
| 217 | 223 | ((unsigned *)ecc[i])[1] = EMC_NFPAR (1) |
| 224 | kdebug_line () |
| 218 | 225 | ecc[i][9] = EMC_NFPAR (2) |
| 226 | kdebug_line () |
| 219 | 227 | // Spare space (starts at 1 << page_bits) |
| 220 | 228 | // 0: unused |
| 221 | 229 | // 2: detect valid data (at least 1 byte == 0 means valid) |
| ... | ... | |
| 228 | 236 | // 64: end of space |
| 229 | 237 | for unsigned i = 0; i < 6; ++i: |
| 230 | 238 | wdata (0) |
| 239 | kdebug_line () |
| 231 | 240 | for unsigned i = 0; i < 4; ++i: |
| 232 | 241 | for unsigned j = 0; j < 9; ++j: |
| 233 | 242 | wdata (ecc[i][j]) |
| 243 | kdebug_line () |
| 234 | 244 | cmd (CMD_PAGEPROG) |
| 245 | kdebug_line () |
| 235 | 246 | Iris::debug ("nand program %d done\n", a) |
| 236 | 247 | |
| 237 | 248 | static void erase (unsigned a): |
| ... | ... | |
| 243 | 254 | cmd (CMD_ERASE2) |
| 244 | 255 | Iris::debug ("nand erase %d done\n", a) |
| 245 | 256 | |
| 257 | extern "C": |
| 258 | extern char file_start, file_end |
| 259 | |
| 246 | 260 | Iris::Num start (): |
| 247 | | kdebug ("starting nand operation in 10 seconds\n") |
| 248 | | Iris::sleep (10 * HZ) |
| 261 | //kdebug ("starting nand operation in 10 seconds\n") |
| 262 | //Iris::sleep (10 * HZ) |
| 249 | 263 | map_emc () |
| 250 | 264 | map_gpio () |
| 251 | 265 | |
| ... | ... | |
| 256 | 270 | |
| 257 | 271 | reset () |
| 258 | 272 | |
| 259 | | char buffer[0x800] |
| 260 | 273 | |
| 261 | | //erase (0) |
| 274 | #if 0 |
| 275 | erase (0) |
| 276 | kdebug_line () |
| 277 | char *source = &file_start |
| 278 | kdebug_line () |
| 279 | unsigned a = 0x0000 |
| 280 | kdebug_line () |
| 281 | while source < &file_end: |
| 282 | kdebug_line () |
| 283 | write (a, source) |
| 284 | a += 0x800 |
| 285 | source += 0x800 |
| 286 | kdebug_line () |
| 287 | #endif |
| 262 | 288 | |
| 289 | char buffer[0x800] |
| 290 | |
| 291 | kdebug_line () |
| 263 | 292 | // Send nand contents to serial port. |
| 264 | | for unsigned a = 0; a < 0x4000; a += 0x200: |
| 293 | for unsigned a = 0; a < 0x2000; a += 0x200: |
| 265 | 294 | read (a, buffer) |
| 266 | | for unsigned s = 0; s < 0x10; ++s: |
| 267 | | for unsigned t = 0; t < 0x20; ++t: |
| 295 | for unsigned s = 0; s < 0x8; ++s: |
| 296 | for unsigned t = 0; t < 0x40; ++t: |
| 268 | 297 | kdebug (" ") |
| 269 | | kdebug_num (buffer[s * 0x20 + t], 2) |
| 298 | kdebug_num (buffer[s * 0x40 + t], 2) |
| 270 | 299 | kdebug ("\n") |
| 271 | 300 | kdebug ("\n") |
| 272 | 301 | // Exit. |
| 273 | 302 | return 0 |
| 303 | |
| 304 | asm volatile ("\t.set noreorder\n" |
| 305 | "\t.globl file_start\n" |
| 306 | "\t.globl file_end\n" |
| 307 | "\t.text\n" |
| 308 | "file_start:\n" |
| 309 | "\t.incbin \"mips/nanonote/nand-boot.raw\"\n" |
| 310 | "file_end:\n" |
| 311 | ".set reorder") |
| source/rtc.ccp |
| 1 | #pypp 0 |
| 2 | // Iris: micro-kernel for a capability-based operating system. |
| 3 | // source/rtc.ccp: real-time clock driver. |
| 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 | |
| 19 | #include "devices.hh" |
| 20 | #define ARCH |
| 21 | #include "arch.hh" |
| 22 | |
| 23 | static void ready (): |
| 24 | while !rtc_write_ready (): |
| 25 | Iris::schedule () |
| 26 | |
| 27 | static unsigned get_second (): |
| 28 | ready () |
| 29 | unsigned ret = rtc_get_second () |
| 30 | unsigned r2 |
| 31 | while true: |
| 32 | ready () |
| 33 | r2 = rtc_get_second () |
| 34 | if ret == r2: |
| 35 | return ret |
| 36 | kdebug ("ret != r2\n") |
| 37 | ret = r2 |
| 38 | |
| 39 | Iris::Num start (): |
| 40 | map_cpm () |
| 41 | map_rtc () |
| 42 | cpm_start_rtc () |
| 43 | ready () |
| 44 | rtc_enabled () |
| 45 | ready () |
| 46 | rtc_set_nc1Hz_val (RTC_CLOCK) |
| 47 | ready () |
| 48 | rtc_enable_1Hz_irq () |
| 49 | rtc_clear_alarm_flag () |
| 50 | rtc_set_hwfcr_val (0) |
| 51 | while true: |
| 52 | ready () |
| 53 | rtc_clear_1Hz_flag () |
| 54 | ready () |
| 55 | Iris::register_interrupt (IRQ_RTC) |
| 56 | Iris::wait () |
| 57 | kdebug ("tick\n") |
| 58 | return 0 |