From e4151e737b765ef0869804b836094f665edf10f1 Mon Sep 17 00:00:00 2001 From: Bas Wijnen Date: Tue, 10 Aug 2010 10:09:50 +0200 Subject: [PATCH] start nand-boot; wrap startup --- init.config | 55 +++++----- invoke.ccp | 2 + iris.hhp | 3 + kernel.hhp | 1 + mips/nanonote/Makefile.arch | 37 ++++--- mips/nanonote/board.ccp | 19 ++++ mips/nanonote/jz4740.hhp | 2 +- mips/nanonote/nand-boot.ccp | 207 ++++++++++++++++++++++++++++++++++++ source/init.ccp | 4 +- source/nand.ccp | 154 +++++++++++++++++---------- source/rtc.ccp | 58 ++++++++++ 11 files changed, 437 insertions(+), 105 deletions(-) create mode 100644 mips/nanonote/nand-boot.ccp create mode 100644 source/rtc.ccp diff --git a/init.config b/init.config index 154f7a4..e61f434 100644 --- a/init.config +++ b/init.config @@ -1,44 +1,45 @@ # driver = '' load a file into memory to be run priviledged. # program = '' load a file into memory to be run normally. - driver driver_lcd = "lcd.elf" - driver driver_buzzer = "buzzer.elf" + #driver driver_lcd = "lcd.elf" + #driver driver_buzzer = "buzzer.elf" driver driver_gpio = "gpio.elf" - program alarm = "alarm.elf" - program gui = "gui.elf" + #program alarm = "alarm.elf" + #program gui = "gui.elf" driver nand = "nand.elf" - driver sdmmc = "sd+mmc.elf" - program partition = "partition.elf" - program fat = "fat.elf" - program test = "test.elf" + #driver sdmmc = "sd+mmc.elf" + #program partition = "partition.elf" + #program fat = "fat.elf" + #program test = "test.elf" + #driver rtc = "rtc.elf" # receive / [, ] = prepare to accept a capability from a named program. - receive driver_lcd / Display = display - receive driver_lcd / Setting = display_bright - receive driver_buzzer / Buzzer = buzzer + #receive driver_lcd / Display = display + #receive driver_lcd / Setting = display_bright + #receive driver_buzzer / Buzzer = buzzer receive driver_gpio / Keyboard , 0 = keyboard receive driver_gpio / Keyboard , 1 = sysreq receive driver_gpio / Event = sdmmc_gpio - receive alarm / UI = ui - receive sdmmc / WString = sdmmc - receive partition / WString, 0 = p0 - receive partition / WString, 1 = p1 - receive partition / WString, 2 = p2 - receive partition / WString, 3 = p3 - receive fat / Directory = root + #receive alarm / UI = ui + #receive sdmmc / WString = sdmmc + #receive partition / WString, 0 = p0 + #receive partition / WString, 1 = p1 + #receive partition / WString, 2 = p2 + #receive partition / WString, 3 = p3 + #receive fat / Directory = root # sysreq use a capability as the system request keyboard. sysreq sysreq # give / [, ] = give this capability to this program when it requests it. - give gui / UI = ui - give gui / Display = display - give gui / Setting = display_bright - give gui / Buzzer = buzzer - give gui / Keyboard = keyboard - give sdmmc / Event = sdmmc_gpio - give partition / WString = sdmmc - give fat / WString = p0 - give test / Directory = root + #give gui / UI = ui + #give gui / Display = display + #give gui / Setting = display_bright + #give gui / Buzzer = buzzer + #give gui / Keyboard = keyboard + #give sdmmc / Event = sdmmc_gpio + #give partition / WString = sdmmc + #give fat / WString = p0 + #give test / Directory = root # include include a file as another config file. diff --git a/invoke.ccp b/invoke.ccp index 1823c23..48bcd31 100644 --- a/invoke.ccp +++ b/invoke.ccp @@ -556,6 +556,8 @@ static void thread_invoke (unsigned cmd, unsigned target, Iris::Num protected_da return case Iris::Thread::PRIV_REBOOT & REQUEST_MASK: arch_reboot () + case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK: + arch_poweroff () case Iris::Thread::PRIV_PANIC & REQUEST_MASK: if c->data[1].l == 0xdeaddead: dbg_code.l = 1 diff --git a/iris.hhp b/iris.hhp index 42d34cb..704cd5f 100644 --- a/iris.hhp +++ b/iris.hhp @@ -322,6 +322,7 @@ namespace Iris: SET_OWNER DBG_SEND PRIV_REBOOT + PRIV_POWEROFF PRIV_PANIC // These get/set_info are not arch-specific. enum info_type: @@ -578,6 +579,8 @@ namespace Iris: my_thread.call (CAP_MASTER_DIRECT | Thread::DBG_SEND, Num (code, bits)) inline void reboot (): my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT) + inline void poweroff (): + my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_POWEROFF) void Receiver::sleep (unsigned value): set_alarm (value) diff --git a/kernel.hhp b/kernel.hhp index d53fc10..1b786b9 100644 --- a/kernel.hhp +++ b/kernel.hhp @@ -322,6 +322,7 @@ void kPage_arch_init (kPage *page) void kPage_arch_update_mapping (kPage *page) void arch_register_interrupt (unsigned num, kReceiverP r) void arch_reboot () +void arch_poweroff () void arch_uncache_page (unsigned page) #define assert(x) do { if (!(x)) panic (__LINE__, "assertion failed"); } while (0) diff --git a/mips/nanonote/Makefile.arch b/mips/nanonote/Makefile.arch index a54772a..77fe067 100644 --- a/mips/nanonote/Makefile.arch +++ b/mips/nanonote/Makefile.arch @@ -17,7 +17,22 @@ start_load = 0xa0600000 load = 0x80000000 -#UDC_BOOT = comment this out for nand boot +UDC_BOOT = comment this out for nand boot + +ifdef UDC_BOOT +boot_threads = $(standard_boot_programs) $(udc_boot_programs) +threadlist = mips/nanonote/threadlist-udc +ARCH_CXXFLAGS = -DNUM_THREADS=2 +all: mips/nanonote/nand-boot.raw test +else +boot_threads = $(standard_boot_programs) $(sd_boot_programs) +threadlist = mips/nanonote/threadlist-sd +ARCH_CXXFLAGS = -DNUM_THREADS=4 +all: mips/nanonote/nand-boot.raw iris-sd.tar +iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config + 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' + cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference +endif ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL CROSS = mipsel-linux-gnu- @@ -26,6 +41,9 @@ junk = mdebug.abi32 reginfo comment pdr OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk)) iris.elf: LDFLAGS = --omagic -Ttext $(load) mips/start.elf: LDFLAGS = --omagic -Ttext $(start_load) +mips/nanonote/nand-boot.elf: LDFLAGS = --omagic -Ttext 0x80000000 + +source/nand.o: mips/nanonote/nand-boot.raw arch_iris_sources = mips/interrupts.cc mips/arch.cc boot_sources = mips/init.cc mips/nanonote/board.cc @@ -34,22 +52,7 @@ udc_boot_programs = udc sd_boot_programs = sd+mmc partition fat standard_boot_programs = bootinit -programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs) - -ifdef UDC_BOOT -boot_threads = $(standard_boot_programs) $(udc_boot_programs) -threadlist = mips/nanonote/threadlist-udc -ARCH_CXXFLAGS = -DNUM_THREADS=2 -all: test -else -boot_threads = $(standard_boot_programs) $(sd_boot_programs) -threadlist = mips/nanonote/threadlist-sd -ARCH_CXXFLAGS = -DNUM_THREADS=4 -all: iris-sd.tar -iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config - 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' - cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference -endif +programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs) mips/start.o:mips/start.S Makefile Makefile.arch iris.raw $(CC) $(CPPFLAGS) -DSTART=0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8') -c $< -o $@ diff --git a/mips/nanonote/board.ccp b/mips/nanonote/board.ccp index f32a5dd..e6edb64 100644 --- a/mips/nanonote/board.ccp +++ b/mips/nanonote/board.ccp @@ -94,3 +94,22 @@ void arch_reboot (): wdt_start () // Wait for wdt to trigger reboot. while true: + +void arch_poweroff (): + // Wait for serial port to be done. + while !(UART0_LSR & UARTLSR_TEMT): + // Power off. + // Make sure the rtc is running. + cpm_start_rtc () + while !rtc_write_ready (): + rtc_enabled () + while !rtc_write_ready (): + rtc_power_down () + // Wait for power down to work. + while !rtc_write_ready (): + // Delay a bit more. + for unsigned i = 0; i < 1000; ++i: + gpio_set (0, 0) + // Fall back to reboot. + kdebug ("Power down failed! Rebooting instead.\n") + arch_reboot () diff --git a/mips/nanonote/jz4740.hhp b/mips/nanonote/jz4740.hhp index f239f0d..740e372 100644 --- a/mips/nanonote/jz4740.hhp +++ b/mips/nanonote/jz4740.hhp @@ -117,7 +117,7 @@ static void __map_io (unsigned physical, unsigned mapping): #define map_intc() do { __map_io (INTC_PHYSICAL, INTC_BASE); } while (0) #define map_tcu() do { __map_io (TCU_PHYSICAL, TCU_BASE); } while (0) #define map_wdt() do { __map_io (WDT_PHYSICAL, WDT_BASE); } while (0) -#define map_rtc() do { __map_io (RTC_PHYSICAL, RTC_BASE); } while (1) +#define map_rtc() do { __map_io (RTC_PHYSICAL, RTC_BASE); } while (0) #define map_gpio() do { __map_io (GPIO_PHYSICAL, GPIO_BASE); } while (0) #define map_aic() do { __map_io (AIC_PHYSICAL, AIC_BASE); } while (0) #define map_msc() do { __map_io (MSC_PHYSICAL, MSC_BASE); } while (0) diff --git a/mips/nanonote/nand-boot.ccp b/mips/nanonote/nand-boot.ccp new file mode 100644 index 0000000..6609565 --- /dev/null +++ b/mips/nanonote/nand-boot.ccp @@ -0,0 +1,207 @@ +#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 +// +// 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 . + +// The following defines are taken from mtd/nand.h in the Linux source. + +asm volatile ("\t.set noreorder\n" + "\t.text\n" + "\t.globl __start\n" + "\t.word ~0\n" + "__start:\n" + "\tbal 1f\n" + "__hack_label:\n" + "\tnop\n" + "\t.word _gp\n" + "1:\n" + "\tlw $gp, 0($ra)\n" + "\tla $sp, stack + 0x1000\n" + "\tla $t9, nandboot_start\n" + "\tjr $t9\n" + "\tnop\n" + "\t.set reorder") + +#define __KERNEL__ +#include + +// Standard NAND flash commands +#define CMD_READ0 0 +#define CMD_READ1 1 +#define CMD_RNDOUT 5 +#define CMD_PAGEPROG 0x10 +#define CMD_READOOB 0x50 +#define CMD_ERASE1 0x60 +#define CMD_STATUS 0x70 +#define CMD_STATUS_MULTI 0x71 +#define CMD_SEQIN 0x80 +#define CMD_RNDIN 0x85 +#define CMD_READID 0x90 +#define CMD_ERASE2 0xd0 +#define CMD_RESET 0xff + +// Extended commands for large page devices +#define CMD_READSTART 0x30 +#define CMD_RNDOUTSTART 0xE0 +#define CMD_CACHEDPROG 0x15 + +// Status bits +#define STATUS_FAIL 0x01 +#define STATUS_FAIL_N1 0x02 +#define STATUS_TRUE_READY 0x20 +#define STATUS_READY 0x40 +#define STATUS_WP 0x80 + +static volatile char *command +static volatile char *address +static volatile char *data + +static unsigned page_bits +static unsigned redundant_bits +static unsigned block_bits +static unsigned word_size + +static void unbusy (): + while !(gpio_get_port (2) & (1 << 30)): + // Do nothing. + // Delay. + for unsigned i = 0; i < 1000; ++i: + gpio_set (0, 0) + +static void addr (unsigned d): + unbusy () + *address = d + unbusy () + +static void cmd (unsigned d): + unbusy () + *command = d + unbusy () + +static void wdata (unsigned d): + unbusy () + *data = d + unbusy () + +static unsigned rdata (): + unbusy () + unsigned ret = *data + unbusy () + return ret + +// Reset nand controller. +static void reset (): + unsigned base = 0xa0000000 + 0x18000000 + data = (volatile char *)base + command = (volatile char *)(base + 0x8000) + address = (volatile char *)(base + 0x10000) + + // Set up. + gpio_as_nand () + EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1 + + // Reset nand. + cmd (CMD_RESET) + + cmd (CMD_READID) + addr (0) + unsigned d = rdata () + //unsigned maker = d + d = rdata () + //unsigned device = d + d = rdata () + //unsigned internal_chip_number = 1 << (d & 0x3) + //unsigned cell_type = 2 << ((d >> 2) & 0x3) + //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3) + //bool can_interleave_program_between_chips = d & 0x40 + //bool can_cache_program = d & 0x80 + d = rdata () + page_bits = 10 + (d & 3) + redundant_bits = (d & 4 ? 4 : 3) + block_bits = 16 + ((d >> 4) & 3) + word_size = (d & 0x40 ? 16 : 8) + //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50) + d = rdata () + //unsigned num_planes = 1 << ((d >> 2) & 3) + //unsigned plane_bits = 26 + ((d >> 4) & 7) + +// Read 512 bytes from nand and store them into buffer. a must be aligned. +// Return value is true if the oob claims there is valid data. +static bool read (unsigned a, char *buffer): + unsigned column = a & ((1 << page_bits) - 1) + unsigned row = a >> page_bits + cmd (CMD_READ0) + addr (column) + addr (column >> 8) + addr (row) + addr (row >> 8) + addr (row >> 16) + cmd (CMD_READSTART) + EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST + for unsigned t = 0; t < 0x200; ++t: + buffer[t] = rdata () + EMC_NFECR = EMC_NFECR_RS | EMC_NFECR_RS_DECODING + char error[9] + // Spare space (starts at 1 << page_bits) + // 0: unused + // 2: detect valid data (at least 1 byte == 0 means valid) + // 5: unused + // 6: 9-byte ecc of 1st 512 bytes + // 15: 9-byte ecc of 2nd 512 bytes + // 24: 9-byte ecc of 3rd 512 bytes + // 33: 9-byte ecc of 4th 512 bytes + // 42: unused + // 64: end of space + unsigned validcol = (1 << page_bits) + 2 + bool valid = false + cmd (CMD_RNDOUT) + addr (validcol) + addr (validcol >> 8) + cmd (CMD_RNDOUTSTART) + for unsigned t = 0; t < 3; ++t: + valid = rdata () == 0 || valid + unsigned errcol = (1 << page_bits) + (column >> 9) * 9 + 6 + cmd (CMD_RNDOUT) + addr (errcol) + addr (errcol >> 8) + cmd (CMD_RNDOUTSTART) + for unsigned t = 0; t < 9; ++t: + error[t] = rdata () + EMC_NFPAR (0) = ((unsigned *)error)[0] + EMC_NFPAR (1) = ((unsigned *)error)[1] + EMC_NFPAR (2) = error[9] + EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY + while !(EMC_NFINTS & EMC_NFINTS_DECF): + // Do nothing. + unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT + for unsigned i = 0; i < errs; ++i: + buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff + +extern "C": + void nandboot_start (): + 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 + // Then jump to 0xa0600000. + return ((void (*)())0xa0600000) () + +unsigned char stack[0x1000] + +unsigned __gxx_personality_v0 diff --git a/source/init.ccp b/source/init.ccp index f6ba32b..53031b3 100644 --- a/source/init.ccp +++ b/source/init.ccp @@ -472,8 +472,8 @@ Iris::Num start (): if Iris::recv.protected_data.l == SYSREQ: if Iris::recv.data[0].l & Iris::Keyboard::RELEASE: continue - kdebug ("sysreq event: rebooting device\n") - Iris::reboot () + kdebug ("sysreq event: powering device off\n") + Iris::poweroff () continue Program *caller = (Program *)Iris::recv.protected_data.l switch Iris::recv.data[0].l: diff --git a/source/nand.ccp b/source/nand.ccp index 5cfd93b..cd2b50e 100644 --- a/source/nand.ccp +++ b/source/nand.ccp @@ -24,49 +24,29 @@ // Standard NAND flash commands #define CMD_READ0 0 -#define CMD_READ1 1 -#define CMD_RNDOUT 5 -#define CMD_PAGEPROG 0x10 -#define CMD_READOOB 0x50 -#define CMD_ERASE1 0x60 -#define CMD_STATUS 0x70 -#define CMD_STATUS_MULTI 0x71 -#define CMD_SEQIN 0x80 -#define CMD_RNDIN 0x85 +#define CMD_READSTART 0x30 + #define CMD_READID 0x90 -#define CMD_ERASE2 0xd0 + #define CMD_RESET 0xff -// Extended commands for large page devices -#define CMD_READSTART 0x30 +#define CMD_SEQIN 0x80 +#define CMD_PAGEPROG 0x10 + +#define CMD_ERASE1 0x60 +#define CMD_ERASE2 0xd0 + +#define CMD_RNDIN 0x85 + +#define CMD_RNDOUT 5 #define CMD_RNDOUTSTART 0xE0 -#define CMD_CACHEDPROG 0x15 -// Extended commands for AG-AND device -// Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but -// there is no way to distinguish that from NAND_CMD_READ0 -// until the remaining sequence of commands has been completed -// so add a high order bit and mask it off in the command. -#define CMD_DEPLETE1 0x100 -#define CMD_DEPLETE2 0x38 -#define CMD_STATUS_MULTI 0x71 -#define CMD_STATUS_ERROR 0x72 -// multi-bank error status (banks 0-3) -#define CMD_STATUS_ERROR0 0x73 -#define CMD_STATUS_ERROR1 0x74 -#define CMD_STATUS_ERROR2 0x75 -#define CMD_STATUS_ERROR3 0x76 -#define CMD_STATUS_RESET 0x7f -#define CMD_STATUS_CLEAR 0xff - -#define CMD_NONE -1 +#define CMD_STATUS 0x70 // Status bits #define STATUS_FAIL 0x01 -#define STATUS_FAIL_N1 0x02 -#define STATUS_TRUE_READY 0x20 #define STATUS_READY 0x40 -#define STATUS_WP 0x80 +#define STATUS_WRITABLE 0x80 static volatile char *command static volatile char *address @@ -154,21 +134,12 @@ static void reset (): //unsigned num_planes = 1 << ((d >> 2) & 3) //unsigned plane_bits = 26 + ((d >> 4) & 7) -static void read (unsigned a, char *buffer): +static bool read (unsigned a, char *buffer): unsigned column = a & ((1 << page_bits) - 1) unsigned row = a >> page_bits //Iris::debug ("reading: %x/%x/%x: ", a, row, column) - cmd (CMD_READ0) - addr (column) - addr (column >> 8) - addr (row) - addr (row >> 8) - addr (row >> 16) - cmd (CMD_READSTART) - EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST - for unsigned t = 0; t < 0x200; ++t: - buffer[t] = rdata () - char error[9] + // Read oob information first. + char error[12] // Spare space (starts at 1 << page_bits) // 0: unused // 2: detect valid data (at least 1 byte == 0 means valid) @@ -179,13 +150,35 @@ static void read (unsigned a, char *buffer): // 33: 9-byte ecc of 4th 512 bytes // 42: unused // 64: end of space - unsigned errcol = (1 << page_bits) + (column >> 9) * 9 + 6 + unsigned col = (1 << page_bits) + 2 + cmd (CMD_READ0) + addr (col) + addr (col >> 8) + addr (row) + addr (row >> 8) + addr (row >> 16) + cmd (CMD_READSTART) + bool valid = false + for unsigned t = 0; t < 3; ++t: + if rdata () == 0: + valid = true + break + if !valid: + return false + col = (1 << page_bits) + 6 + 9 * (column >> 9) cmd (CMD_RNDOUT) - addr (errcol) - addr (errcol >> 8) + addr (col) + addr (col >> 8) cmd (CMD_RNDOUTSTART) for unsigned t = 0; t < 9; ++t: error[t] = rdata () + cmd (CMD_RNDOUT) + addr (column) + addr (column >> 8) + cmd (CMD_RNDOUTSTART) + EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST + for unsigned t = 0; t < 0x200; ++t: + buffer[t] = rdata () EMC_NFPAR (0) = ((unsigned *)error)[0] EMC_NFPAR (1) = ((unsigned *)error)[1] EMC_NFPAR (2) = error[9] @@ -198,24 +191,39 @@ static void read (unsigned a, char *buffer): buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff static void write (unsigned a, char *buffer): + kdebug_line () unsigned row = a >> page_bits + kdebug_line () //Iris::debug ("writing: %x/%x: ", a, row) cmd (CMD_SEQIN) + kdebug_line () addr (0) + kdebug_line () addr (0) + kdebug_line () addr (row) + kdebug_line () addr (row >> 8) + kdebug_line () addr (row >> 16) - char ecc[4][9] + kdebug_line () + char ecc[4][12] for unsigned i = 0; i < 0x4; ++i: + kdebug_line () EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING | EMC_NFECR_ERST + Iris::debug ("writing data from %x\n", (unsigned)buffer + i * 0x200) for unsigned j = 0; j < 0x200; ++j: wdata (buffer[i * 0x200 + j]) + kdebug_line () while !(EMC_NFINTS & EMC_NFINTS_ENCF): Iris::schedule () + kdebug_line () ((unsigned *)ecc[i])[0] = EMC_NFPAR (0) + kdebug_line () ((unsigned *)ecc[i])[1] = EMC_NFPAR (1) + kdebug_line () ecc[i][9] = EMC_NFPAR (2) + kdebug_line () // Spare space (starts at 1 << page_bits) // 0: unused // 2: detect valid data (at least 1 byte == 0 means valid) @@ -228,10 +236,13 @@ static void write (unsigned a, char *buffer): // 64: end of space for unsigned i = 0; i < 6; ++i: wdata (0) + kdebug_line () for unsigned i = 0; i < 4; ++i: for unsigned j = 0; j < 9; ++j: wdata (ecc[i][j]) + kdebug_line () cmd (CMD_PAGEPROG) + kdebug_line () Iris::debug ("nand program %d done\n", a) static void erase (unsigned a): @@ -243,9 +254,12 @@ static void erase (unsigned a): cmd (CMD_ERASE2) Iris::debug ("nand erase %d done\n", a) +extern "C": + extern char file_start, file_end + Iris::Num start (): - kdebug ("starting nand operation in 10 seconds\n") - Iris::sleep (10 * HZ) + //kdebug ("starting nand operation in 10 seconds\n") + //Iris::sleep (10 * HZ) map_emc () map_gpio () @@ -256,18 +270,42 @@ Iris::Num start (): reset () + + #if 0 + erase (0) + kdebug_line () + char *source = &file_start + kdebug_line () + unsigned a = 0x0000 + kdebug_line () + while source < &file_end: + kdebug_line () + write (a, source) + a += 0x800 + source += 0x800 + kdebug_line () + #endif + char buffer[0x800] - //erase (0) - + kdebug_line () // Send nand contents to serial port. - for unsigned a = 0; a < 0x4000; a += 0x200: + for unsigned a = 0; a < 0x2000; a += 0x200: read (a, buffer) - for unsigned s = 0; s < 0x10; ++s: - for unsigned t = 0; t < 0x20; ++t: + for unsigned s = 0; s < 0x8; ++s: + for unsigned t = 0; t < 0x40; ++t: kdebug (" ") - kdebug_num (buffer[s * 0x20 + t], 2) + kdebug_num (buffer[s * 0x40 + t], 2) kdebug ("\n") kdebug ("\n") // Exit. return 0 + +asm volatile ("\t.set noreorder\n" + "\t.globl file_start\n" + "\t.globl file_end\n" + "\t.text\n" + "file_start:\n" + "\t.incbin \"mips/nanonote/nand-boot.raw\"\n" + "file_end:\n" + ".set reorder") diff --git a/source/rtc.ccp b/source/rtc.ccp new file mode 100644 index 0000000..64d627f --- /dev/null +++ b/source/rtc.ccp @@ -0,0 +1,58 @@ +#pypp 0 +// Iris: micro-kernel for a capability-based operating system. +// source/rtc.ccp: real-time clock driver. +// Copyright 2010 Bas Wijnen +// +// 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 . + +#include "devices.hh" +#define ARCH +#include "arch.hh" + +static void ready (): + while !rtc_write_ready (): + Iris::schedule () + +static unsigned get_second (): + ready () + unsigned ret = rtc_get_second () + unsigned r2 + while true: + ready () + r2 = rtc_get_second () + if ret == r2: + return ret + kdebug ("ret != r2\n") + ret = r2 + +Iris::Num start (): + map_cpm () + map_rtc () + cpm_start_rtc () + ready () + rtc_enabled () + ready () + rtc_set_nc1Hz_val (RTC_CLOCK) + ready () + rtc_enable_1Hz_irq () + rtc_clear_alarm_flag () + rtc_set_hwfcr_val (0) + while true: + ready () + rtc_clear_1Hz_flag () + ready () + Iris::register_interrupt (IRQ_RTC) + Iris::wait () + kdebug ("tick\n") + return 0