mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 14:14:18 +01:00
untested NAND IPC support which breaks nandfs
i'll test this and port nandfs to the powerpc tomorrow
This commit is contained in:
parent
513926130a
commit
1eef8e083c
4
ipc.c
4
ipc.c
@ -6,6 +6,7 @@
|
|||||||
#include "hollywood.h"
|
#include "hollywood.h"
|
||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
#include "nand.h"
|
||||||
|
|
||||||
static volatile ipc_request in_queue[IPC_IN_SIZE] ALIGNED(32) MEM2_BSS;
|
static volatile ipc_request in_queue[IPC_IN_SIZE] ALIGNED(32) MEM2_BSS;
|
||||||
static volatile ipc_request out_queue[IPC_OUT_SIZE] ALIGNED(32) MEM2_BSS;
|
static volatile ipc_request out_queue[IPC_OUT_SIZE] ALIGNED(32) MEM2_BSS;
|
||||||
@ -91,6 +92,9 @@ static int process_slow(volatile ipc_request *req)
|
|||||||
gecko_printf("IPC: unknown SLOW SYS request %04x\n", req->req);
|
gecko_printf("IPC: unknown SLOW SYS request %04x\n", req->req);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IPC_DEV_NAND:
|
||||||
|
nand_ipc(req);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req);
|
gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req);
|
||||||
}
|
}
|
||||||
|
99
nand.c
99
nand.c
@ -6,6 +6,8 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "gecko.h"
|
||||||
|
|
||||||
//#define NAND_DEBUG 1
|
//#define NAND_DEBUG 1
|
||||||
#undef NAND_SUPPORT_WRITE
|
#undef NAND_SUPPORT_WRITE
|
||||||
@ -41,13 +43,19 @@ type *name = (type*)(((u32)(_al__##name)) + ((alignment) - (( \
|
|||||||
#define PAGE_SIZE 2048
|
#define PAGE_SIZE 2048
|
||||||
#define PAGE_SPARE_SIZE 64
|
#define PAGE_SPARE_SIZE 64
|
||||||
|
|
||||||
static int irq = 0;
|
static int ipc_code = 0;
|
||||||
|
static int ipc_tag = 0;
|
||||||
|
|
||||||
void nand_irq(void)
|
void nand_irq(void)
|
||||||
{
|
{
|
||||||
irq = 1;
|
int code, tag;
|
||||||
|
if (ipc_code != 0) {
|
||||||
|
code = ipc_code;
|
||||||
|
tag = ipc_tag;
|
||||||
|
ipc_code = ipc_tag = 0;
|
||||||
|
ipc_post(code, tag, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline u32 __nand_read32(u32 addr)
|
static inline u32 __nand_read32(u32 addr)
|
||||||
{
|
{
|
||||||
@ -72,7 +80,6 @@ void nand_send_command(u32 command, u32 bitmask, u32 flags, u32 num_bytes) {
|
|||||||
__nand_write32(NAND_CMD, 0x7fffffff);
|
__nand_write32(NAND_CMD, 0x7fffffff);
|
||||||
__nand_write32(NAND_CMD, 0);
|
__nand_write32(NAND_CMD, 0);
|
||||||
__nand_write32(NAND_CMD, cmd);
|
__nand_write32(NAND_CMD, cmd);
|
||||||
__nand_wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __nand_set_address(s32 page_off, s32 pageno) {
|
void __nand_set_address(s32 page_off, s32 pageno) {
|
||||||
@ -97,6 +104,7 @@ int nand_reset(void)
|
|||||||
{
|
{
|
||||||
NAND_debug("nand_reset()\n");
|
NAND_debug("nand_reset()\n");
|
||||||
nand_send_command(NAND_RESET, 0, 0x8000, 0);
|
nand_send_command(NAND_RESET, 0, 0x8000, 0);
|
||||||
|
__nand_wait();
|
||||||
// yay cargo cult
|
// yay cargo cult
|
||||||
__nand_write32(NAND_CONF, 0x8000000);
|
__nand_write32(NAND_CONF, 0x8000000);
|
||||||
__nand_write32(NAND_CONF, 0x4b3e0e7f);
|
__nand_write32(NAND_CONF, 0x4b3e0e7f);
|
||||||
@ -117,6 +125,7 @@ u32 nand_get_id(void) {
|
|||||||
|
|
||||||
__nand_setup_dma(idbuf, (u8 *)-1);
|
__nand_setup_dma(idbuf, (u8 *)-1);
|
||||||
nand_send_command(NAND_CHIPID, 1, 0x2000, 0x40);
|
nand_send_command(NAND_CHIPID, 1, 0x2000, 0x40);
|
||||||
|
__nand_wait();
|
||||||
NAND_debug("id = %02hx%02hx%02hx%02hx (post)\n", idbuf[0], idbuf[1], idbuf[2], idbuf[3]);
|
NAND_debug("id = %02hx%02hx%02hx%02hx (post)\n", idbuf[0], idbuf[1], idbuf[2], idbuf[3]);
|
||||||
|
|
||||||
return idbuf[0] << 24 | idbuf[1] << 16 | idbuf[2] << 8 | idbuf[3];
|
return idbuf[0] << 24 | idbuf[1] << 16 | idbuf[2] << 8 | idbuf[3];
|
||||||
@ -128,18 +137,13 @@ u32 nand_get_status(void) {
|
|||||||
dc_flushrange(status_buf, 0x40);
|
dc_flushrange(status_buf, 0x40);
|
||||||
__nand_setup_dma(status_buf, (u8 *)-1);
|
__nand_setup_dma(status_buf, (u8 *)-1);
|
||||||
nand_send_command(NAND_GETSTATUS, 0, 0x2000, 0x40);
|
nand_send_command(NAND_GETSTATUS, 0, 0x2000, 0x40);
|
||||||
|
__nand_wait();
|
||||||
dc_invalidaterange(status_buf, 0x40);
|
dc_invalidaterange(status_buf, 0x40);
|
||||||
return status_buf[0];
|
return status_buf[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void __nand_wait_irq(void) {
|
|
||||||
while(irq == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nand_read_page(u32 pageno, void *data, void *ecc) {
|
void nand_read_page(u32 pageno, void *data, void *ecc) {
|
||||||
NAND_debug("nand_read_page(%u, %p, %p)\n", pageno, data, ecc);
|
NAND_debug("nand_read_page(%u, %p, %p)\n", pageno, data, ecc);
|
||||||
#if 1
|
|
||||||
irq = 0;
|
|
||||||
__nand_set_address(0, pageno);
|
__nand_set_address(0, pageno);
|
||||||
nand_send_command(NAND_READ_PRE, 0x1f, 0, 0);
|
nand_send_command(NAND_READ_PRE, 0x1f, 0, 0);
|
||||||
|
|
||||||
@ -148,34 +152,9 @@ void nand_read_page(u32 pageno, void *data, void *ecc) {
|
|||||||
|
|
||||||
__nand_setup_dma(data, ecc);
|
__nand_setup_dma(data, ecc);
|
||||||
nand_send_command(NAND_READ_POST, 0, 0x4000b000, 0x840);
|
nand_send_command(NAND_READ_POST, 0, 0x4000b000, 0x840);
|
||||||
|
|
||||||
__nand_wait_irq();
|
|
||||||
#else
|
|
||||||
int i;
|
|
||||||
unsigned char *c_data = (unsigned char *)data;
|
|
||||||
unsigned char *c_ecc = (unsigned char *)ecc;
|
|
||||||
for(i=0; i<0x800; i++) c_data[i] = pageno % 256;
|
|
||||||
for(i=0; i<0x40; i++) c_ecc = pageno % 256;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: do we really need to read the ECC data?
|
|
||||||
static u8 ecc[64] __attribute__((aligned(32))) MEM2_BSS;
|
|
||||||
void nand_read_cluster(u32 clusterno, void *data) {
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 8; i++)
|
|
||||||
nand_read_page((clusterno*8) + i, data + (i * PAGE_SIZE), ecc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nand_read_decrypted_cluster(u32 clusterno, void *data) {
|
|
||||||
nand_read_cluster(clusterno, data);
|
|
||||||
aes_reset();
|
|
||||||
aes_set_key(otp.nand_key);
|
|
||||||
aes_empty_iv();
|
|
||||||
aes_decrypt(data, data, 0x400, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NAND_SUPPORT_WRITE
|
#ifdef NAND_SUPPORT_WRITE
|
||||||
void nand_write_page(u32 pageno, void *data, void *ecc) {
|
void nand_write_page(u32 pageno, void *data, void *ecc) {
|
||||||
NAND_debug("nand_write_page(%u, %p, %p)\n", pageno, data, ecc);
|
NAND_debug("nand_write_page(%u, %p, %p)\n", pageno, data, ecc);
|
||||||
@ -200,7 +179,53 @@ void nand_erase_block(u32 pageno) {
|
|||||||
|
|
||||||
void nand_initialize(void)
|
void nand_initialize(void)
|
||||||
{
|
{
|
||||||
irq_enable(IRQ_NAND);
|
ipc_code = ipc_tag = 0;
|
||||||
irq = 0;
|
|
||||||
nand_reset();
|
nand_reset();
|
||||||
|
irq_enable(IRQ_NAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nand_ipc(volatile ipc_request *req)
|
||||||
|
{
|
||||||
|
if (ipc_code != 0 || ipc_tag != 0) {
|
||||||
|
gecko_printf("NAND: previous IPC request is not done yet.");
|
||||||
|
ipc_post(req->code, req->tag, 1, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (req->req) {
|
||||||
|
case IPC_NAND_RESET:
|
||||||
|
nand_reset();
|
||||||
|
ipc_post(req->code, req->tag, 1, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPC_NAND_GETID:
|
||||||
|
ipc_post(req->code, req->tag, 2, 0, nand_get_id());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPC_NAND_READ:
|
||||||
|
ipc_code = req->code;
|
||||||
|
ipc_tag = req->tag;
|
||||||
|
nand_read_page(req->args[0], (void *)req->args[1],
|
||||||
|
(void *)req->args[1]);
|
||||||
|
break;
|
||||||
|
#ifdef NAND_SUPPORT_WRITE
|
||||||
|
case IPC_NAND_WRITE:
|
||||||
|
ipc_code = req->code;
|
||||||
|
ipc_tag = req->tag;
|
||||||
|
nand_write_page(req->args[0], (void *)req->args[1],
|
||||||
|
(void *)req->args[1]);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef NAND_SUPPORT_ERASE
|
||||||
|
case IPC_NAND_ERASE:
|
||||||
|
ipc_code = req->code;
|
||||||
|
ipc_tag = req->tag;
|
||||||
|
nand_erase_block(req->args[0]);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
gecko_printf("IPC: unknown SLOW NAND request %04x\n",
|
||||||
|
req->req);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
nand.h
4
nand.h
@ -2,6 +2,7 @@
|
|||||||
#define __NAND_H__
|
#define __NAND_H__
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "ipc.h"
|
||||||
|
|
||||||
void nand_irq(void);
|
void nand_irq(void);
|
||||||
|
|
||||||
@ -14,8 +15,9 @@ void nand_write_page(u32 pageno, void *data, void *ecc);
|
|||||||
void nand_erase_block(u32 pageno);
|
void nand_erase_block(u32 pageno);
|
||||||
|
|
||||||
void nand_read_cluster(u32 clusterno, void *data);
|
void nand_read_cluster(u32 clusterno, void *data);
|
||||||
void nand_read_decrypted_cluster(u32 clusterno, void *data);
|
|
||||||
|
|
||||||
void nand_initialize();
|
void nand_initialize();
|
||||||
|
|
||||||
|
void nand_ipc(volatile ipc_request *req);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
6
nandfs.c
6
nandfs.c
@ -63,8 +63,8 @@ s32 nandfs_initialize()
|
|||||||
|
|
||||||
for(i = 0; i < sizeof(struct _nandfs_sffs)/(PAGE_SIZE*8);
|
for(i = 0; i < sizeof(struct _nandfs_sffs)/(PAGE_SIZE*8);
|
||||||
i++) {
|
i++) {
|
||||||
nand_read_cluster(supercluster + i,
|
/* nand_read_cluster(supercluster + i,
|
||||||
((u8 *)&sffs) + (i * PAGE_SIZE * 8));
|
((u8 *)&sffs) + (i * PAGE_SIZE * 8));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
@ -155,7 +155,7 @@ s32 nandfs_read(void *ptr, u32 size, u32 nmemb, struct nandfs_fp *fp)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while(total > 0) {
|
while(total > 0) {
|
||||||
nand_read_decrypted_cluster(fp->cur_cluster, buffer);
|
// nand_read_decrypted_cluster(fp->cur_cluster, buffer);
|
||||||
copy_offset = fp->offset % (PAGE_SIZE * 8);
|
copy_offset = fp->offset % (PAGE_SIZE * 8);
|
||||||
copy_len = (PAGE_SIZE * 8) - copy_offset;
|
copy_len = (PAGE_SIZE * 8) - copy_offset;
|
||||||
if(copy_len > total)
|
if(copy_len > total)
|
||||||
|
Loading…
Reference in New Issue
Block a user