mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-29 03:21:09 +02:00
make booting from sd work
This commit is contained in:
parent
a277156a2e
commit
19f1d128d0
@ -78,7 +78,7 @@ namespace Iris:
|
|||||||
/// Set the size of the string. Strings may have a limit to this setting.
|
/// Set the size of the string. Strings may have a limit to this setting.
|
||||||
void truncate (Num size):
|
void truncate (Num size):
|
||||||
call (CAP_MASTER_DIRECT | TRUNCATE, size)
|
call (CAP_MASTER_DIRECT | TRUNCATE, size)
|
||||||
/// Set exactly 4 characters. The index must be word-aligned.
|
/// Set exactly 4 characters. The index must be aligned. This need not be supported for strings with align larger than 4 bytes.
|
||||||
void set_chars (Num idx, char buffer[4]):
|
void set_chars (Num idx, char buffer[4]):
|
||||||
call (Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
|
call (Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
|
||||||
/// Overwrite a block from the string with data at offset on the page. This need not be implemented for strings smaller than PAGE_SIZE. The all arguments must be aligned. The caller may lose the frame in the transaction. Only the specified part of the page is used for overwriting data.
|
/// Overwrite a block from the string with data at offset on the page. This need not be implemented for strings smaller than PAGE_SIZE. The all arguments must be aligned. The caller may lose the frame in the transaction. Only the specified part of the page is used for overwriting data.
|
||||||
|
28
init.config
28
init.config
@ -1,24 +1,24 @@
|
|||||||
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
# driver <name> = '<filename>' load a file into memory to be run priviledged.
|
||||||
# program <name> = '<filename>' load a file into memory to be run normally.
|
# program <name> = '<filename>' load a file into memory to be run normally.
|
||||||
#driver driver_lcd = "lcd.elf"
|
driver driver_lcd = "lcd.elf"
|
||||||
#driver driver_buzzer = "buzzer.elf"
|
driver driver_buzzer = "buzzer.elf"
|
||||||
driver driver_gpio = "gpio.elf"
|
driver driver_gpio = "gpio.elf"
|
||||||
#program alarm = "alarm.elf"
|
program alarm = "alarm.elf"
|
||||||
#program gui = "gui.elf"
|
program gui = "gui.elf"
|
||||||
#driver nand = "nand.elf"
|
driver nand = "nand.elf"
|
||||||
driver sdmmc = "sd+mmc.elf"
|
driver sdmmc = "sd+mmc.elf"
|
||||||
program partition = "partition.elf"
|
program partition = "partition.elf"
|
||||||
program fat = "fat.elf"
|
program fat = "fat.elf"
|
||||||
program test = "test.elf"
|
program test = "test.elf"
|
||||||
|
|
||||||
# receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
|
# receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
|
||||||
#receive driver_lcd / Display = display
|
receive driver_lcd / Display = display
|
||||||
#receive driver_lcd / Setting = display_bright
|
receive driver_lcd / Setting = display_bright
|
||||||
#receive driver_buzzer / Buzzer = buzzer
|
receive driver_buzzer / Buzzer = buzzer
|
||||||
receive driver_gpio / Keyboard , 0 = keyboard
|
receive driver_gpio / Keyboard , 0 = keyboard
|
||||||
receive driver_gpio / Keyboard , 1 = sysreq
|
receive driver_gpio / Keyboard , 1 = sysreq
|
||||||
receive driver_gpio / Event = sdmmc_gpio
|
receive driver_gpio / Event = sdmmc_gpio
|
||||||
#receive alarm / UI = ui
|
receive alarm / UI = ui
|
||||||
receive sdmmc / WString = sdmmc
|
receive sdmmc / WString = sdmmc
|
||||||
receive partition / WString, 0 = p0
|
receive partition / WString, 0 = p0
|
||||||
receive partition / WString, 1 = p1
|
receive partition / WString, 1 = p1
|
||||||
@ -30,11 +30,11 @@
|
|||||||
sysreq sysreq
|
sysreq sysreq
|
||||||
|
|
||||||
# give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
|
# give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
|
||||||
#give gui / UI = ui
|
give gui / UI = ui
|
||||||
#give gui / Display = display
|
give gui / Display = display
|
||||||
#give gui / Setting = display_bright
|
give gui / Setting = display_bright
|
||||||
#give gui / Buzzer = buzzer
|
give gui / Buzzer = buzzer
|
||||||
#give gui / Keyboard = keyboard
|
give gui / Keyboard = keyboard
|
||||||
give sdmmc / Event = sdmmc_gpio
|
give sdmmc / Event = sdmmc_gpio
|
||||||
give partition / WString = sdmmc
|
give partition / WString = sdmmc
|
||||||
give fat / WString = p0
|
give fat / WString = p0
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
UDC_BOOT=1
|
#UDC_BOOT = set
|
||||||
|
|
||||||
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define ELFRUN_NAME "elfrun.elf"
|
#define ELFRUN_NAME "elfrun.elf"
|
||||||
#define INIT_NAME "init.elf"
|
#define INIT_NAME "init.elf"
|
||||||
|
|
||||||
|
// These numbers are only used for elfrun.
|
||||||
#define NUM_SLOTS 8
|
#define NUM_SLOTS 8
|
||||||
#define NUM_CAPS 32
|
#define NUM_CAPS 32
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ namespace Iris:
|
|||||||
__recv_data_t recv
|
__recv_data_t recv
|
||||||
|
|
||||||
void print_caps ():
|
void print_caps ():
|
||||||
// Assume __caps to be 32.
|
// __caps cannot be larger than 63.
|
||||||
bool used[32]
|
bool used[63]
|
||||||
for unsigned i = 0; i < 32; ++i:
|
for unsigned i = 0; i < __caps; ++i:
|
||||||
used[i] = true
|
used[i] = true
|
||||||
unsigned num = 0
|
unsigned num = 0
|
||||||
for list *i = __first_free_cap; i; i = i->next:
|
for list *i = __first_free_cap; i; i = i->next:
|
||||||
@ -52,7 +52,7 @@ namespace Iris:
|
|||||||
++num
|
++num
|
||||||
kdebug_num (num, 2)
|
kdebug_num (num, 2)
|
||||||
kdebug (":")
|
kdebug (":")
|
||||||
for unsigned i = 0; i < 32; ++i:
|
for unsigned i = 0; i < __caps; ++i:
|
||||||
kdebug_char (used[i] ? '#' : '.')
|
kdebug_char (used[i] ? '#' : '.')
|
||||||
kdebug_char ('\n')
|
kdebug_char ('\n')
|
||||||
|
|
||||||
|
@ -296,9 +296,9 @@ struct Fat:
|
|||||||
else if bits == 12 && fat[c] == 0xfff || bits == 16 && fat[c] == 0xffff || bits == 32 && fat[c] == 0xfffffff:
|
else if bits == 12 && fat[c] == 0xfff || bits == 16 && fat[c] == 0xffff || bits == 32 && fat[c] == 0xfffffff:
|
||||||
// Last cluster in chain.
|
// Last cluster in chain.
|
||||||
fat[c] = ~0
|
fat[c] = ~0
|
||||||
kdebug ("last cluster: ")
|
//kdebug ("last cluster: ")
|
||||||
kdebug_num (c)
|
//kdebug_num (c)
|
||||||
kdebug ("\n")
|
//kdebug ("\n")
|
||||||
else if bits == 12 && fat[c] == 0xff7 || bits == 16 && fat[c] == 0xfff7 || bits == 32 && fat[c] == 0xffffff7:
|
else if bits == 12 && fat[c] == 0xff7 || bits == 16 && fat[c] == 0xfff7 || bits == 32 && fat[c] == 0xffffff7:
|
||||||
// Bad cluster.
|
// Bad cluster.
|
||||||
fat[c] = first_bad_cluster
|
fat[c] = first_bad_cluster
|
||||||
@ -307,10 +307,10 @@ struct Fat:
|
|||||||
else:
|
else:
|
||||||
// Non-last cluster in chain.
|
// Non-last cluster in chain.
|
||||||
fat[c] -= 2
|
fat[c] -= 2
|
||||||
kdebug_num (c)
|
//kdebug_num (c)
|
||||||
kdebug (" -> ")
|
//kdebug (" -> ")
|
||||||
kdebug_num (fat[c])
|
//kdebug_num (fat[c])
|
||||||
kdebug ("\n")
|
//kdebug ("\n")
|
||||||
unsigned fat_lookup (unsigned first_cluster, unsigned cluster):
|
unsigned fat_lookup (unsigned first_cluster, unsigned cluster):
|
||||||
//kdebug ("looking up ")
|
//kdebug ("looking up ")
|
||||||
//kdebug_num (first_cluster)
|
//kdebug_num (first_cluster)
|
||||||
@ -334,20 +334,19 @@ struct Fat:
|
|||||||
bool archive, readonly, system, hidden, directory, volume
|
bool archive, readonly, system, hidden, directory, volume
|
||||||
unsigned create_second, create_minute_hour, create_date, access_date, time, date
|
unsigned create_second, create_minute_hour, create_date, access_date, time, date
|
||||||
unsigned checksum
|
unsigned checksum
|
||||||
void load_cluster (unsigned idx, Iris::Page p = page, unsigned offset = 0):
|
void load_cluster (unsigned idx, unsigned offset_in_cluster, Iris::Page p = page, unsigned offset = 0):
|
||||||
unsigned cluster = fat->fat_lookup (first_cluster, idx >> fat->cluster_size_bits)
|
unsigned cluster = fat->fat_lookup (first_cluster, idx >> fat->cluster_size_bits)
|
||||||
//kdebug ("loading cluster ")
|
//kdebug ("loading cluster ")
|
||||||
//kdebug_num (idx)
|
//kdebug_num (idx)
|
||||||
|
//kdebug ("+")
|
||||||
|
//kdebug_num (offset_in_cluster)
|
||||||
//kdebug ("@")
|
//kdebug ("@")
|
||||||
//kdebug_num (cluster)
|
//kdebug_num (cluster)
|
||||||
//kdebug (" from file\n")
|
//kdebug (" from file\n")
|
||||||
if cluster == ~0:
|
if cluster == ~0:
|
||||||
kdebug ("invalid cluster requested from file\n")
|
kdebug ("invalid cluster requested from file\n")
|
||||||
return
|
return
|
||||||
read_block ((fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits)) << fat->sector_size_bits, p, 1 << fat->cluster_size_bits, offset)
|
read_block (((fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits)) << fat->sector_size_bits) + offset_in_cluster, p, fat->cluster_size_bits < PAGE_BITS ? 1 << fat->cluster_size_bits : PAGE_SIZE, offset)
|
||||||
//kdebug ("sector ")
|
|
||||||
//kdebug_num (fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits))
|
|
||||||
//kdebug ("\n")
|
|
||||||
char *load_dir_entry (unsigned dir, unsigned idx):
|
char *load_dir_entry (unsigned dir, unsigned idx):
|
||||||
unsigned sector = idx >> (sector_size_bits - 5)
|
unsigned sector = idx >> (sector_size_bits - 5)
|
||||||
unsigned num = (idx << 5) & ~BLOCK_MASK
|
unsigned num = (idx << 5) & ~BLOCK_MASK
|
||||||
@ -398,8 +397,11 @@ struct Fat:
|
|||||||
kdebug ("unable to load dir entry\n")
|
kdebug ("unable to load dir entry\n")
|
||||||
return false
|
return false
|
||||||
f->fat = this
|
f->fat = this
|
||||||
|
//kdebug ("loading dir entry for ")
|
||||||
for unsigned i = 0; i < 11; ++i:
|
for unsigned i = 0; i < 11; ++i:
|
||||||
f->name[i] = e[i]
|
f->name[i] = e[i]
|
||||||
|
//kdebug_char (f->name[i])
|
||||||
|
//kdebug ("\n")
|
||||||
f->readonly = e[0xb] & 0x1
|
f->readonly = e[0xb] & 0x1
|
||||||
f->system = e[0xb] & 0x2
|
f->system = e[0xb] & 0x2
|
||||||
f->hidden = e[0xb] & 0x4
|
f->hidden = e[0xb] & 0x4
|
||||||
@ -589,8 +591,6 @@ Iris::Num start ():
|
|||||||
unsigned size = Iris::recv.data[0].h >> 16
|
unsigned size = Iris::recv.data[0].h >> 16
|
||||||
unsigned offset = Iris::recv.data[0].h & 0xffff
|
unsigned offset = Iris::recv.data[0].h & 0xffff
|
||||||
unsigned cmd = Iris::recv.data[0].l
|
unsigned cmd = Iris::recv.data[0].l
|
||||||
if !fat.find_idx (dir, &idx):
|
|
||||||
Iris::panic (0, "file not found")
|
|
||||||
Fat::File f
|
Fat::File f
|
||||||
fat.get_dir_entry (dir, idx, &f)
|
fat.get_dir_entry (dir, idx, &f)
|
||||||
switch cmd:
|
switch cmd:
|
||||||
@ -600,26 +600,30 @@ Iris::Num start ():
|
|||||||
break
|
break
|
||||||
case Iris::String::GET_CHARS:
|
case Iris::String::GET_CHARS:
|
||||||
//kdebug ("file chars requested\n")
|
//kdebug ("file chars requested\n")
|
||||||
unsigned mask = 1 << (fat.cluster_size_bits) - 1
|
unsigned mask = (1 << fat.cluster_size_bits) - 1
|
||||||
f.load_cluster (num.l & ~mask)
|
f.load_cluster (num.l & ~mask, num.l & mask)
|
||||||
unsigned n = num.l & mask & ~0xf
|
unsigned n = num.l & mask & ~0xf
|
||||||
unsigned *dat = (unsigned *)(data + n)
|
unsigned *dat = (unsigned *)(data + n)
|
||||||
reply.invoke (Iris::Num (dat[0], dat[1]), Iris::Num (dat[2], dat[3]))
|
reply.invoke (Iris::Num (dat[0], dat[1]), Iris::Num (dat[2], dat[3]))
|
||||||
break
|
break
|
||||||
case Iris::String::GET_ALIGN_BITS:
|
case Iris::String::GET_ALIGN_BITS:
|
||||||
//kdebug ("file align requested\n")
|
//kdebug ("file align requested\n")
|
||||||
reply.invoke (fat.cluster_size_bits)
|
reply.invoke (fat.cluster_size_bits <= PAGE_BITS ? fat.cluster_size_bits : PAGE_BITS)
|
||||||
break
|
break
|
||||||
case Iris::String::GET_BLOCK:
|
case Iris::String::GET_BLOCK:
|
||||||
//kdebug ("file block requested\n")
|
//kdebug ("file block requested\n")
|
||||||
unsigned mask = 1 << (fat.cluster_size_bits) - 1
|
unsigned mask = (1 << fat.cluster_size_bits) - 1
|
||||||
|
//kdebug ("mask = ")
|
||||||
|
//kdebug_num (mask)
|
||||||
|
//kdebug ("\n")
|
||||||
if offset > PAGE_SIZE:
|
if offset > PAGE_SIZE:
|
||||||
//kdebug ("invalid offset requested\n")
|
//kdebug ("invalid offset requested\n")
|
||||||
break
|
break
|
||||||
if size + offset > PAGE_SIZE:
|
if size + offset > PAGE_SIZE:
|
||||||
|
Iris::panic (size, "invalid size requested")
|
||||||
size = PAGE_SIZE - offset
|
size = PAGE_SIZE - offset
|
||||||
for unsigned i = 0; i < size; i += 1 << fat.cluster_size_bits:
|
for unsigned i = 0; i < size; i += 1 << fat.cluster_size_bits:
|
||||||
f.load_cluster ((num.l & ~mask) + i, arg, i + offset)
|
f.load_cluster ((num.l & ~mask) + i, num.l & mask, arg, i + offset)
|
||||||
reply.invoke ()
|
reply.invoke ()
|
||||||
break
|
break
|
||||||
case Iris::WString::TRUNCATE:
|
case Iris::WString::TRUNCATE:
|
||||||
@ -652,12 +656,18 @@ Iris::Num start ():
|
|||||||
Iris::Cap reply = Iris::get_reply ()
|
Iris::Cap reply = Iris::get_reply ()
|
||||||
dir = Iris::recv.protected_data.l
|
dir = Iris::recv.protected_data.l
|
||||||
unsigned idx = Iris::recv.data[1].l
|
unsigned idx = Iris::recv.data[1].l
|
||||||
|
unsigned oldidx = idx
|
||||||
if !fat.find_idx (dir, &idx):
|
if !fat.find_idx (dir, &idx):
|
||||||
Iris::panic (0, "file not found")
|
kdebug_num (oldidx)
|
||||||
|
kdebug ("\n")
|
||||||
|
Iris::panic (1, "file not found")
|
||||||
Fat::File f
|
Fat::File f
|
||||||
fat.get_dir_entry (dir, idx, &f)
|
fat.get_dir_entry (dir, idx, &f)
|
||||||
Iris::Cap ret
|
Iris::Cap ret
|
||||||
if f.directory:
|
if f.directory:
|
||||||
|
//kdebug ("dir provided: ")
|
||||||
|
//kdebug_num (f.first_cluster)
|
||||||
|
//kdebug ("\n")
|
||||||
ret = Iris::my_receiver.create_capability (Iris::Num (f.first_cluster, 0))
|
ret = Iris::my_receiver.create_capability (Iris::Num (f.first_cluster, 0))
|
||||||
else:
|
else:
|
||||||
ret = Iris::my_receiver.create_capability (Iris::Num (idx, dir))
|
ret = Iris::my_receiver.create_capability (Iris::Num (idx, dir))
|
||||||
@ -670,8 +680,11 @@ Iris::Num start ():
|
|||||||
Iris::Cap reply = Iris::get_reply ()
|
Iris::Cap reply = Iris::get_reply ()
|
||||||
dir = Iris::recv.protected_data.l
|
dir = Iris::recv.protected_data.l
|
||||||
unsigned idx = Iris::recv.data[1].l
|
unsigned idx = Iris::recv.data[1].l
|
||||||
|
unsigned oldidx = idx
|
||||||
if !fat.find_idx (dir, &idx):
|
if !fat.find_idx (dir, &idx):
|
||||||
Iris::panic (0, "file not found")
|
kdebug_num (oldidx)
|
||||||
|
kdebug ("\n")
|
||||||
|
Iris::panic (2, "file not found")
|
||||||
unsigned type = Iris::recv.data[0].h
|
unsigned type = Iris::recv.data[0].h
|
||||||
Fat::File f
|
Fat::File f
|
||||||
fat.get_dir_entry (dir, idx, &f)
|
fat.get_dir_entry (dir, idx, &f)
|
||||||
|
@ -143,6 +143,7 @@ struct Program:
|
|||||||
Iris::free_cap (cap)
|
Iris::free_cap (cap)
|
||||||
thread = caps.get (__thread_num)
|
thread = caps.get (__thread_num)
|
||||||
memory = caps.get (__memory_num)
|
memory = caps.get (__memory_num)
|
||||||
|
Iris::free_cap (caps)
|
||||||
if priv:
|
if priv:
|
||||||
thread.make_priv ()
|
thread.make_priv ()
|
||||||
thread.run ()
|
thread.run ()
|
||||||
@ -471,7 +472,8 @@ Iris::Num start ():
|
|||||||
if Iris::recv.protected_data.l == SYSREQ:
|
if Iris::recv.protected_data.l == SYSREQ:
|
||||||
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
|
||||||
continue
|
continue
|
||||||
kdebug ("sysreq event\n")
|
kdebug ("sysreq event: rebooting device\n")
|
||||||
|
Iris::reboot ()
|
||||||
continue
|
continue
|
||||||
Program *caller = (Program *)Iris::recv.protected_data.l
|
Program *caller = (Program *)Iris::recv.protected_data.l
|
||||||
switch Iris::recv.data[0].l:
|
switch Iris::recv.data[0].l:
|
||||||
|
@ -173,8 +173,8 @@ static void read (unsigned a, char *buffer):
|
|||||||
unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
|
unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
|
||||||
|
|
||||||
Iris::Num start ():
|
Iris::Num start ():
|
||||||
for unsigned i = 0; i < 30; ++i:
|
kdebug ("reading nand in 10 seconds\n")
|
||||||
Iris::schedule ()
|
Iris::sleep (10 * HZ)
|
||||||
map_emc ()
|
map_emc ()
|
||||||
map_gpio ()
|
map_gpio ()
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ class Mmc:
|
|||||||
public:
|
public:
|
||||||
enum Response_type:
|
enum Response_type:
|
||||||
NONE = MSC_CMDAT_RESPONSE_NONE
|
NONE = MSC_CMDAT_RESPONSE_NONE
|
||||||
DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN
|
RD_DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN | MSC_CMDAT_READ
|
||||||
|
WR_DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE
|
||||||
R1 = MSC_CMDAT_RESPONSE_R1
|
R1 = MSC_CMDAT_RESPONSE_R1
|
||||||
R1B = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_BUSY
|
R1B = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_BUSY
|
||||||
R2 = MSC_CMDAT_RESPONSE_R2
|
R2 = MSC_CMDAT_RESPONSE_R2
|
||||||
@ -68,6 +69,8 @@ class Mmc:
|
|||||||
unsigned get_block_bits ():
|
unsigned get_block_bits ():
|
||||||
return hc ? 9 : csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len
|
return hc ? 9 : csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len
|
||||||
void fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
|
void fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
|
||||||
|
void write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
|
||||||
|
void wait_write ()
|
||||||
private:
|
private:
|
||||||
unsigned rca
|
unsigned rca
|
||||||
bool have_sdmem, have_io
|
bool have_sdmem, have_io
|
||||||
@ -82,9 +85,11 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne
|
|||||||
MSC_CMD = cmd
|
MSC_CMD = cmd
|
||||||
MSC_ARG = arg
|
MSC_ARG = arg
|
||||||
MSC_CMDAT = response_type
|
MSC_CMDAT = response_type
|
||||||
|
MSC_IMASK = ~MSC_IMASK_END_CMD_RES
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
msc_start_op ()
|
msc_start_op ()
|
||||||
Iris::wait_for_interrupt (IRQ_MSC)
|
Iris::wait_for_interrupt (IRQ_MSC)
|
||||||
|
MSC_IMASK = ~0
|
||||||
//kdebug ("cmd: ")
|
//kdebug ("cmd: ")
|
||||||
//kdebug_num (cmd)
|
//kdebug_num (cmd)
|
||||||
unsigned stat = MSC_STAT
|
unsigned stat = MSC_STAT
|
||||||
@ -178,6 +183,10 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne
|
|||||||
else if r >> 8 != cmd:
|
else if r >> 8 != cmd:
|
||||||
kdebug ("stat: ")
|
kdebug ("stat: ")
|
||||||
kdebug_num (MSC_STAT)
|
kdebug_num (MSC_STAT)
|
||||||
|
kdebug ("; response: ")
|
||||||
|
kdebug_num (r)
|
||||||
|
kdebug ("; cmd: ")
|
||||||
|
kdebug_num (cmd)
|
||||||
Iris::panic (r, "response doesn't match command")
|
Iris::panic (r, "response doesn't match command")
|
||||||
r <<= 24
|
r <<= 24
|
||||||
r |= MSC_RES << 8
|
r |= MSC_RES << 8
|
||||||
@ -199,8 +208,8 @@ void Mmc::reset ():
|
|||||||
Iris::my_memory.map (buffer_page, buffer)
|
Iris::my_memory.map (buffer_page, buffer)
|
||||||
// Reset all state, by faking a release event.
|
// Reset all state, by faking a release event.
|
||||||
release ()
|
release ()
|
||||||
// Enable slow clock to msc.
|
// Enable 25 MHz clock to msc.
|
||||||
CPM_MSCCDR = ~0
|
CPM_MSCCDR = 13
|
||||||
cpm_start_msc ()
|
cpm_start_msc ()
|
||||||
// Enable msc pins.
|
// Enable msc pins.
|
||||||
gpio_as_msc ()
|
gpio_as_msc ()
|
||||||
@ -223,13 +232,13 @@ void Mmc::reset ():
|
|||||||
Iris::sleep (1)
|
Iris::sleep (1)
|
||||||
|
|
||||||
// Initialize registers.
|
// Initialize registers.
|
||||||
MSC_CLKRT = MSC_CLKRT_CLK_RATE_DIV_128
|
MSC_CLKRT = MSC_CLKRT_CLK_RATE_DIV_1
|
||||||
MSC_RESTO = 64
|
MSC_RESTO = 64
|
||||||
MSC_RDTO = ~0
|
MSC_RDTO = ~0
|
||||||
MSC_BLKLEN = 0x200
|
MSC_BLKLEN = 0x200
|
||||||
MSC_NOB = 0
|
MSC_NOB = 0
|
||||||
MSC_IREG = ~0
|
MSC_IREG = ~0
|
||||||
MSC_IMASK = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_RXFIFO_RD_REQ | MSC_IMASK_TXFIFO_WR_REQ)
|
MSC_IMASK = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_RXFIFO_RD_REQ)
|
||||||
MSC_ARG = 0
|
MSC_ARG = 0
|
||||||
|
|
||||||
// Start the clock.
|
// Start the clock.
|
||||||
@ -237,8 +246,8 @@ void Mmc::reset ():
|
|||||||
// Set cards, if any, to idle.
|
// Set cards, if any, to idle.
|
||||||
send (0, 0, NONE)
|
send (0, 0, NONE)
|
||||||
|
|
||||||
// Reset SDIO device, if any.
|
// Reset SDIO device, if any. Don't do this, because it breaks for some reason.
|
||||||
send (52, 0x88000c08, R5)
|
//send (52, 0x88000c08, R5)
|
||||||
|
|
||||||
void Mmc::check_mmc ():
|
void Mmc::check_mmc ():
|
||||||
//kdebug ("checking mmc\n")
|
//kdebug ("checking mmc\n")
|
||||||
@ -378,8 +387,9 @@ void Mmc::fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned
|
|||||||
//kdebug ("/")
|
//kdebug ("/")
|
||||||
//kdebug_num (size)
|
//kdebug_num (size)
|
||||||
//kdebug (" ==> ")
|
//kdebug (" ==> ")
|
||||||
if !send (17, p + a, DATA):
|
if !send (17, p + a, RD_DATA):
|
||||||
Iris::panic (0, "unable to request data")
|
Iris::panic (0, "unable to request data")
|
||||||
|
MSC_IMASK = ~MSC_IMASK_RXFIFO_RD_REQ
|
||||||
for unsigned aa = 0; aa < 1 << 9; aa += 4:
|
for unsigned aa = 0; aa < 1 << 9; aa += 4:
|
||||||
while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
|
while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
|
||||||
Iris::register_interrupt (IRQ_MSC)
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
@ -392,9 +402,48 @@ void Mmc::fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned
|
|||||||
//kdebug (" ")
|
//kdebug (" ")
|
||||||
//kdebug_num (d >> (8 * i), 2)
|
//kdebug_num (d >> (8 * i), 2)
|
||||||
//kdebug ("\n")
|
//kdebug ("\n")
|
||||||
|
MSC_IMASK = ~0
|
||||||
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
||||||
//kdebug ("done filling page\n")
|
//kdebug ("done filling page\n")
|
||||||
|
|
||||||
|
void Mmc::write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset):
|
||||||
|
if address.h:
|
||||||
|
Iris::panic (1, "page too high: not supported")
|
||||||
|
return
|
||||||
|
unsigned blockmask = ~((1 << 9) - 1)
|
||||||
|
unsigned p = address.l & blockmask
|
||||||
|
size &= blockmask
|
||||||
|
offset &= ~PAGE_MASK
|
||||||
|
if size + offset > PAGE_SIZE:
|
||||||
|
size = PAGE_SIZE - offset
|
||||||
|
page.share (buffer_page)
|
||||||
|
buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
|
||||||
|
MSC_NOB = 1
|
||||||
|
MSC_BLKLEN = 1 << 9
|
||||||
|
for unsigned a = 0; a < size; a += 1 << 9:
|
||||||
|
//kdebug_num (a)
|
||||||
|
//kdebug ("/")
|
||||||
|
//kdebug_num (size)
|
||||||
|
//kdebug ("\n")
|
||||||
|
if !send (24, p + a, WR_DATA):
|
||||||
|
Iris::panic (0, "unable to send data")
|
||||||
|
MSC_IMASK = ~MSC_IMASK_TXFIFO_WR_REQ
|
||||||
|
for unsigned aa = 0; aa < 1 << 9; aa += 4:
|
||||||
|
while MSC_STAT & MSC_STAT_DATA_FIFO_FULL:
|
||||||
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
|
Iris::wait_for_interrupt (IRQ_MSC)
|
||||||
|
MSC_TXFIFO = *(unsigned *)(buffer + a + aa + offset)
|
||||||
|
MSC_IMASK = ~0
|
||||||
|
MSC_IREG = MSC_IREG_DATA_TRAN_DONE
|
||||||
|
//kdebug ("done writing page\n")
|
||||||
|
|
||||||
|
void Mmc::wait_write ():
|
||||||
|
MSC_IMASK = ~MSC_IMASK_PRG_DONE
|
||||||
|
while !MSC_STAT & MSC_STAT_PRG_DONE:
|
||||||
|
Iris::register_interrupt (IRQ_MSC)
|
||||||
|
Iris::wait_for_interrupt (IRQ_MSC)
|
||||||
|
MSC_IREG = MSC_IREG_PRG_DONE
|
||||||
|
|
||||||
static Mmc mmc
|
static Mmc mmc
|
||||||
|
|
||||||
enum types:
|
enum types:
|
||||||
@ -464,10 +513,19 @@ Iris::Num start ():
|
|||||||
Iris::free_cap (page)
|
Iris::free_cap (page)
|
||||||
Iris::free_cap (reply)
|
Iris::free_cap (reply)
|
||||||
break
|
break
|
||||||
case Iris::WString::SET_CHARS:
|
|
||||||
case Iris::WString::SET_BLOCK:
|
case Iris::WString::SET_BLOCK:
|
||||||
// Fall through: don't support writing yet.
|
Iris::Cap reply = Iris::get_reply ()
|
||||||
|
Iris::Page page = Iris::get_arg ()
|
||||||
|
mmc.write_page (page, Iris::recv.data[1], Iris::recv.data[0].h >> 16, Iris::recv.data[0].h & 0xffff)
|
||||||
|
reply.invoke ()
|
||||||
|
Iris::free_cap (page)
|
||||||
|
Iris::free_cap (reply)
|
||||||
|
mmc.wait_write ()
|
||||||
|
break
|
||||||
|
case Iris::WString::SET_CHARS:
|
||||||
|
// Fall through: don't support writing single characters.
|
||||||
case Iris::WString::TRUNCATE:
|
case Iris::WString::TRUNCATE:
|
||||||
|
// Fall through: don't support resizing.
|
||||||
default:
|
default:
|
||||||
Iris::panic (0, "unexpected event for sd+mmc")
|
Iris::panic (0, "unexpected event for sd+mmc")
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user