Add/rename/fix ahb stuff

This commit is contained in:
marcan 2009-03-07 20:15:07 +01:00 committed by bushing
parent 52f2309ef7
commit 526c6d3865
3 changed files with 81 additions and 79 deletions

View File

@ -62,27 +62,32 @@ u32 _mc_read32(u32 addr)
return data; return data;
} }
void _magic_bullshit(int type) { void _ahb_flush_to(enum AHBDEV dev) {
u32 mask = 10; u32 mask = 10;
switch(type) { switch(dev) {
case 0: mask = 0x8000; break; case AHB_STARLET: mask = 0x8000; break;
case 1: mask = 0x4000; break; case AHB_1: mask = 0x4000; break;
case 2: mask = 0x0001; break; //case 2: mask = 0x0001; break;
case 3: mask = 0x0002; break; case AHB_NAND: mask = 0x0002; break;
case 4: mask = 0x0004; break; //case 4: mask = 0x0004; break;
case 5: mask = 0x0008; break; //case 5: mask = 0x0008; break;
case 6: mask = 0x0010; break; //case 6: mask = 0x0010; break;
case 7: mask = 0x0020; break; //case 7: mask = 0x0020; break;
case 8: mask = 0x0040; break; //case 8: mask = 0x0040; break;
case 9: mask = 0x0080; break; //case 9: mask = 0x0080; break;
case 10: mask = 0x0100; break; //case 10: mask = 0x0100; break;
case 11: mask = 0x1000; break; //case 11: mask = 0x1000; break;
case 12: mask = 0x0000; break; //case 12: mask = 0x0000; break;
default:
gecko_printf("ahb_invalidate(%d): Invalid device\n", dev);
return;
} }
//NOTE: 0xd8b000x, not 0xd8b400x! //NOTE: 0xd8b000x, not 0xd8b400x!
u32 val = _mc_read32(0xd8b0008); u32 val = _mc_read32(0xd8b0008);
if(val & mask) { if(val & mask) {
if((type >= 2) && (type <= 10)) { switch(dev) {
// 2 to 10 in IOS, add more
case AHB_NAND:
while((read32(HW_18C) & 0xF) == 9) while((read32(HW_18C) & 0xF) == 9)
set32(HW_188, 0x10000); set32(HW_188, 0x10000);
clear32(HW_188, 0x10000); clear32(HW_188, 0x10000);
@ -113,8 +118,9 @@ void _magic_bullshit(int type) {
clear32(HW_120, 0x400); clear32(HW_120, 0x400);
clear32(HW_188, 0x2000000); clear32(HW_188, 0x2000000);
mask32(HW_124, 0x7c0, 0xc0); mask32(HW_124, 0x7c0, 0xc0);
} else { //0, 1, 11 in IOS, add more
if((type == 11) || (type == 0) || (type == 1)) { case AHB_STARLET:
case AHB_1:
write32(0xd8b0008, val & (~mask)); write32(0xd8b0008, val & (~mask));
// wtfux // wtfux
write32(0xd8b0008, val | mask); write32(0xd8b0008, val | mask);
@ -122,19 +128,20 @@ void _magic_bullshit(int type) {
write32(0xd8b0008, val | mask); write32(0xd8b0008, val | mask);
} }
} }
}
} }
void magic_bullshit(int type) // invalidate device and then starlet
void ahb_flush_to(enum AHBDEV type)
{ {
u32 cookie = irq_kill(); u32 cookie = irq_kill();
_magic_bullshit(type); _ahb_flush_to(type);
if(type != 0) if(type != 0)
_magic_bullshit(0); _ahb_flush_to(AHB_STARLET);
irq_restore(cookie); irq_restore(cookie);
} }
void ahb_memflush(enum AHBDEV dev) // flush device and also invalidate memory
void ahb_flush_from(enum AHBDEV dev)
{ {
u32 cookie = irq_kill(); u32 cookie = irq_kill();
u16 req = 0; u16 req = 0;
@ -143,34 +150,29 @@ void ahb_memflush(enum AHBDEV dev)
switch(dev) switch(dev)
{ {
case MEMORY: case AHB_STARLET:
case AHB_1:
req = 1; req = 1;
break; break;
case NAND: case AHB_NAND:
req = 8; req = 8;
break; break;
default: default:
if((dev >= RAW0) && (dev <= RAWF)) gecko_printf("ahb_flush(%d): Invalid device\n", dev);
{
req = dev - RAW0;
} else {
gecko_printf("ahb_memflush(0x%x): Invalid device\n", dev);
return; return;
} }
break;
}
write16(MEM_FLUSHREQ, req); write16(MEM_FLUSHREQ, req);
for(i=0;i<1000000;i++) { for(i=0;i<1000000;i++) {
ack = read16(MEM_FLUSHACK); ack = read16(MEM_FLUSHACK);
_magic_bullshit(0); _ahb_flush_to(AHB_STARLET);
if(ack == req) if(ack == req)
break; break;
} }
write16(MEM_FLUSHREQ, 0); write16(MEM_FLUSHREQ, 0);
if(i>=1000000) { if(i>=1000000) {
gecko_printf("ahb_memflush(%d): Flush (0x%x) did not ack!\n", dev, req); gecko_printf("ahb_flush(%d): Flush (0x%x) did not ack!\n", dev, req);
} }
irq_restore(cookie); irq_restore(cookie);
} }
@ -186,7 +188,7 @@ void dc_flushrange(const void *start, u32 size)
_dc_flush_entries(start, (end - start) / LINESIZE); _dc_flush_entries(start, (end - start) / LINESIZE);
} }
_drain_write_buffer(); _drain_write_buffer();
ahb_memflush(MEMORY); ahb_flush_from(AHB_1);
irq_restore(cookie); irq_restore(cookie);
} }
@ -196,7 +198,7 @@ void dc_invalidaterange(void *start, u32 size)
void *end = ALIGN_FORWARD(((u8*)start) + size, LINESIZE); void *end = ALIGN_FORWARD(((u8*)start) + size, LINESIZE);
start = ALIGN_BACKWARD(start, LINESIZE); start = ALIGN_BACKWARD(start, LINESIZE);
_dc_inval_entries(start, (end - start) / LINESIZE); _dc_inval_entries(start, (end - start) / LINESIZE);
_magic_bullshit(0); ahb_flush_to(AHB_STARLET);
irq_restore(cookie); irq_restore(cookie);
} }
@ -205,7 +207,7 @@ void dc_flushall(void)
u32 cookie = irq_kill(); u32 cookie = irq_kill();
_dc_flush(); _dc_flush();
_drain_write_buffer(); _drain_write_buffer();
ahb_memflush(MEMORY); ahb_flush_from(AHB_1);
irq_restore(cookie); irq_restore(cookie);
} }
@ -213,7 +215,7 @@ void ic_invalidateall(void)
{ {
u32 cookie = irq_kill(); u32 cookie = irq_kill();
_ic_inval(); _ic_inval();
_magic_bullshit(0); ahb_flush_to(AHB_STARLET);
irq_restore(cookie); irq_restore(cookie);
} }

View File

@ -10,18 +10,17 @@
((typeof(x))(((u32)(x)) & (~(align-1)))) ((typeof(x))(((u32)(x)) & (~(align-1))))
enum AHBDEV { enum AHBDEV {
MEMORY = 0, AHB_STARLET = 0, //or MEM2??
NAND, AHB_1 = 1, //or MEM1??
RAW0 = 0x100, AHB_NAND = 3,
RAWF = 0x10F,
}; };
void dc_flushrange(const void *start, u32 size); void dc_flushrange(const void *start, u32 size);
void dc_invalidaterange(void *start, u32 size); void dc_invalidaterange(void *start, u32 size);
void dc_flushall(void); void dc_flushall(void);
void ic_invalidateall(void); void ic_invalidateall(void);
void magic_bullshit(int type); void ahb_flush_from(enum AHBDEV dev);
void ahb_memflush(enum AHBDEV dev); void ahb_flush_to(enum AHBDEV dev);
void mem_protect(int enable, void *start, void *end); void mem_protect(int enable, void *start, void *end);
void mem_setswap(int enable); void mem_setswap(int enable);

9
nand.c
View File

@ -71,8 +71,8 @@ void nand_irq(void)
gecko_printf("NAND: Error on IRQ\n"); gecko_printf("NAND: Error on IRQ\n");
err = -1; err = -1;
} }
ahb_memflush(NAND); ahb_flush_from(AHB_NAND);
magic_bullshit(0); ahb_flush_to(AHB_STARLET);
if (current_request.code != 0) { if (current_request.code != 0) {
switch (current_request.req) { switch (current_request.req) {
case IPC_NAND_GETID: case IPC_NAND_GETID:
@ -102,8 +102,8 @@ inline void __nand_wait(void) {
while(__nand_read32(NAND_CMD) & NAND_BUSY_MASK); while(__nand_read32(NAND_CMD) & NAND_BUSY_MASK);
if(__nand_read32(NAND_CMD) & NAND_ERROR) if(__nand_read32(NAND_CMD) & NAND_ERROR)
gecko_printf("NAND: Error on wait\n"); gecko_printf("NAND: Error on wait\n");
ahb_memflush(NAND); ahb_flush_from(AHB_NAND);
magic_bullshit(0); ahb_flush_to(AHB_STARLET);
} }
void nand_send_command(u32 command, u32 bitmask, u32 flags, u32 num_bytes) { void nand_send_command(u32 command, u32 bitmask, u32 flags, u32 num_bytes) {
@ -192,6 +192,7 @@ void nand_write_page(u32 pageno, void *data, void *ecc) {
} }
dc_flushrange(data, PAGE_SIZE); dc_flushrange(data, PAGE_SIZE);
dc_flushrange(ecc, PAGE_SPARE_SIZE); dc_flushrange(ecc, PAGE_SPARE_SIZE);
ahb_flush_to(AHB_NAND);
__nand_set_address(0, pageno); __nand_set_address(0, pageno);
__nand_setup_dma(data, ecc); __nand_setup_dma(data, ecc);
nand_send_command(NAND_WRITE_PRE, 0x1f, NAND_FLAGS_IRQ | NAND_FLAGS_WR | NAND_FLAGS_ECC, 0x840); nand_send_command(NAND_WRITE_PRE, 0x1f, NAND_FLAGS_IRQ | NAND_FLAGS_WR | NAND_FLAGS_ECC, 0x840);