diff --git a/Makefile b/Makefile index c8d8afb..9a10393 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ TARGET = iosboot.bin ELF = iosboot.elf OBJECTS = start.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ utils_asm.o utils.o ff.o diskio.o sdhc.o powerpc_elf.o powerpc.o panic.o irq.o irq_asm.o \ - exception.o exception_asm.o crypto.o nand.o + exception.o exception_asm.o seeprom.o crypto.o nand.o $(TARGET) : $(ELF) $(ELFLOADER) @echo "MAKEBIN $@" diff --git a/crypto.c b/crypto.c index f352e7a..1aca8f6 100644 --- a/crypto.c +++ b/crypto.c @@ -6,12 +6,13 @@ #include "ipc.h" #include "gecko.h" #include "string.h" - +#include "seeprom.h" #define AES_CMD_RESET 0 #define AES_CMD_DECRYPT 0x9800 otp_t otp; +seeprom_t seeprom; void crypto_read_otp(void) { @@ -23,10 +24,15 @@ void crypto_read_otp(void) } } +void crypto_read_seeprom(void) +{ + seeprom_read(&seeprom, 0, sizeof(seeprom) / 2); +} void crypto_initialize() { crypto_read_otp(); + crypto_read_seeprom(); write32(AES_CMD, 0); while (read32(AES_CMD) != 0); irq_enable(IRQ_AES); @@ -40,6 +46,10 @@ void crypto_ipc(volatile ipc_request *req) memcpy((void *)req->args[0], &otp, sizeof(otp)); dc_flushrange((void *)req->args[0], sizeof(otp)); break; + case IPC_KEYS_GETEEP: + memcpy((void *)req->args[0], &seeprom, sizeof(seeprom)); + dc_flushrange((void *)req->args[0], sizeof(seeprom)); + break; default: gecko_printf("IPC: unknown SLOW CRYPTO request %04x\n", req->req); diff --git a/seeprom.c b/seeprom.c new file mode 100644 index 0000000..59feb10 --- /dev/null +++ b/seeprom.c @@ -0,0 +1,64 @@ +#include "types.h" +#include "utils.h" +#include "hollywood.h" +#include "start.h" + +#define gpio_delay() udelay(100) + + +void send_bits(int b, int bits) +{ + while(bits--) + { + if(b & (1 << bits)) + set32(HW_GPIO1OUT, 0x1000); + else + clear32(HW_GPIO1OUT, 0x1000); + gpio_delay(); + set32(HW_GPIO1OUT, 0x800); + gpio_delay(); + clear32(HW_GPIO1OUT, 0x800); + gpio_delay(); + } +} + +int recv_bits(int bits) +{ + int res = 0; + while(bits--) + { + res <<= 1; + set32(HW_GPIO1OUT, 0x800); + gpio_delay(); + clear32(HW_GPIO1OUT, 0x800); + gpio_delay(); + res |= !!(read32(HW_GPIO1IN) & 0x2000); + } + return res; +} + +int seeprom_read(void *dst, int offset, int size) +{ + int i; + u16 *ptr = (u16 *)dst; + u16 recv; + + if(size & 1) + return -1; + + clear32(HW_GPIO1OUT, 0x800); + clear32(HW_GPIO1OUT, 0x400); + gpio_delay(); + + for(i = 0; i < size; ++i) + { + set32(HW_GPIO1OUT, 0x400); + send_bits((0x600 | (offset + i)), 11); + recv = recv_bits(16); + *ptr++ = recv; + clear32(HW_GPIO1OUT, 0x400); + gpio_delay(); + } + + return size; +} diff --git a/seeprom.h b/seeprom.h new file mode 100644 index 0000000..b8f63a5 --- /dev/null +++ b/seeprom.h @@ -0,0 +1,6 @@ +#ifndef __SEEPROM_H__ +#define __SEEPROM_H__ 1 + +int seeprom_read(void *dst, int offset, int size); + +#endif