diff --git a/Makefile b/Makefile index 8e93076..ee6212d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include ../toolchain.rules -CFLAGS = -mbig-endian -fomit-frame-pointer -Os -Wall -I. +CFLAGS = -mbig-endian -fomit-frame-pointer -Os -Wall -I. ASFLAGS = -mbig-endian LDFLAGS = -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,miniios.ld,-Map,miniios.map -n LIBS = -lgcc @@ -10,8 +10,8 @@ MAKEBIN = python ../makebin.py TARGET = miniios.bin ELF = miniios.elf -OBJECTS = start.o main.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 +OBJECTS = start.o ipcstruct.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 $(TARGET) : $(ELF) $(ELFLOADER) @echo "MAKEBIN $@" @@ -23,7 +23,7 @@ $(ELF) : miniios.ld $(OBJECTS) %.o : %.S @echo "AS $@" - @$(AS) $(ASFLAGS) -o $@ $< + @$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $< %.o : %.c @echo "CC $@" diff --git a/diskio.c b/diskio.c index af33687..56cfd86 100644 --- a/diskio.c +++ b/diskio.c @@ -10,7 +10,7 @@ #include static sdhci_t sdhci; -static u8 *buffer[512] __attribute__((aligned(32))); +static u8 buffer[512] MEM2_BSS ALIGNED(32); /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ diff --git a/hollywood.h b/hollywood.h index 0486e9f..3ece9e3 100644 --- a/hollywood.h +++ b/hollywood.h @@ -131,6 +131,8 @@ // maybe a GPIO??? #define HW_RESETS (HW_REG_BASE + 0x194) +#define HW_CLOCKS (HW_REG_BASE + 0x1b4) + #define HW_GPIO2OUT (HW_REG_BASE + 0x1c8) #define HW_GPIO2DIR (HW_REG_BASE + 0x1cc) #define HW_GPIO2IN (HW_REG_BASE + 0x1d0) diff --git a/ipc.c b/ipc.c new file mode 100644 index 0000000..e69de29 diff --git a/ipcstruct.S b/ipcstruct.S new file mode 100644 index 0000000..a79547c --- /dev/null +++ b/ipcstruct.S @@ -0,0 +1,29 @@ +#include "ipcstruct.h" + + .section .rodata.ipc,"a",%progbits + .globl ipc_header + .type ipc_header, %object + .size ipc_header, 32 + .align 5 +ipc_header: + .ascii "IPC1" + .long 0 + .long ipc_in + .long 32 + .long ipc_out + .long 32 + + .section .bss.ipc,"aw",%nobits + .globl ipc_in + .type ipc_in, %object + .size ipc_in, 32 * IPC_IN_SIZE + .align 5 +ipc_in: + .space 32 * IPC_IN_SIZE + + .globl ipc_out + .type ipc_out, %object + .size ipc_out, 32 * IPC_OUT_SIZE + .align 5 +ipc_out: + .space 32 * IPC_IN_SIZE diff --git a/ipcstruct.h b/ipcstruct.h new file mode 100644 index 0000000..2cb63bd --- /dev/null +++ b/ipcstruct.h @@ -0,0 +1,11 @@ +#ifndef __IPCSTRUCT_H__ +#define __IPCSTRUCT_H__ + +#define IPC_IN_SIZE 32 +#define IPC_OUT_SIZE 32 + +#ifndef _LANGUAGE_ASSEMBLY + +#endif + +#endif diff --git a/irq.c b/irq.c new file mode 100644 index 0000000..80088af --- /dev/null +++ b/irq.c @@ -0,0 +1,81 @@ +#include "irq.h" +#include "hollywood.h" +#include "gecko.h" +#include "utils.h" + +void irq_setup_stack(void); + +void irq_initialize(void) +{ + irq_setup_stack(); + write32(HW_IRQENABLE, 0); + write32(HW_IRQFLAG, 0xffffffff); + irq_restore(CPSR_FIQDIS); + + //??? + write32(HW_IRQENABLE+0x04, 0); + write32(HW_IRQENABLE+0x20, 0); +} + +void irq_shutdown(void) +{ + write32(HW_IRQENABLE, 0); + write32(HW_IRQFLAG, 0xffffffff); + irq_kill(); +} + +void irq_handler(void) +{ + u32 enabled = read32(HW_IRQENABLE); + u32 flags = read32(HW_IRQFLAG); + + gecko_printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", enabled, flags, flags & enabled); + + flags = flags & enabled; + + if(flags & IRQF_TIMER) { + gecko_printf("IRQ: timer\n"); + gecko_printf("Timer: %08x\n", read32(HW_TIMER)); + gecko_printf("Alarm: %08x\n", read32(HW_ALARM)); + write32(HW_ALARM, 0); // shut it up + write32(HW_IRQFLAG, IRQF_TIMER); + } + if(flags & IRQF_NAND) { + gecko_printf("IRQ: NAND\n"); + write32(NAND_CMD, 0x7fffffff); // shut it up + write32(HW_IRQFLAG, IRQF_NAND); + } + if(flags & IRQF_GPIO1B) { + gecko_printf("IRQ: GPIO1B\n"); + write32(HW_GPIO1BINTFLAG, 0xFFFFFF); // shut it up + write32(HW_IRQFLAG, IRQF_GPIO1B); + } + if(flags & IRQF_GPIO1) { + gecko_printf("IRQ: GPIO1\n"); + write32(HW_GPIO1INTFLAG, 0xFFFFFF); // shut it up + write32(HW_IRQFLAG, IRQF_GPIO1); + } + if(flags & IRQF_RESET) { + gecko_printf("IRQ: RESET\n"); + write32(HW_IRQFLAG, IRQF_RESET); + } + if(flags & IRQF_IPC) { + gecko_printf("IRQ: IPC\n"); + write32(HW_IRQFLAG, IRQF_IPC); + } + flags &= ~IRQF_ALL; + if(flags) { + gecko_printf("IRQ: unknown 0x%08x\n"); + write32(HW_IRQFLAG, flags); + } +} + +void irq_enable(u32 irq) +{ + set32(HW_IRQENABLE, 1<mem2 + .bss.ipc : + { + *(.bss.ipc) + . = ALIGN(4); + } >mem2 + + .rodata.mem2 : + { + *(.rodata.mem2) + . = ALIGN(4); + } >mem2 + + .data.mem2 : + { + *(.data.mem2) + . = ALIGN(4); + } >mem2 + + .bss.mem2 : + { + __bss2_start = . ; + *(.bss.mem2) + . = ALIGN(4); + __bss2_end = . ; + } >mem2 + .init : { *(.init) . = ALIGN(4); - } + } >sram .text : { + *(.text*) *(.text.*) *(.gnu.warning) *(.gnu.linkonce.t*) *(.glue_7) *(.glue_7t) . = ALIGN(4); - } - - __text_end = . ; - - . = __data_addr; + } >sram .rodata : { @@ -41,7 +71,7 @@ SECTIONS *(.rodata.*) *(.gnu.linkonce.r*) . = ALIGN(4); - } + } >sram2 .data : { @@ -49,7 +79,7 @@ SECTIONS *(.data.*) *(.gnu.linkonce.d*) . = ALIGN(4); - } + } >sram2 .bss : { @@ -61,23 +91,27 @@ SECTIONS *(COMMON) . = ALIGN(4); __bss_end = . ; - } + } >sram2 - . = __stack_area; .stack : { __stack_end = .; - . += 0x800; - LONG(0); + . = . +__stack_size; . = ALIGN(64); __stack_addr = .; - } - - __end = .; - + __irqstack_end = .; + . = . +__irqstack_size; + . = ALIGN(64); + __irqstack_addr = .; + } >sram2 + } PROVIDE (__stack_end = __stack_end); PROVIDE (__stack_addr = __stack_addr); +PROVIDE (__irqstack_end = __irqstack_end); +PROVIDE (__irqstack_addr = __irqstack_addr); PROVIDE (__bss_start = __bss_start); PROVIDE (__bss_end = __bss_end); +PROVIDE (__bss2_start = __bss2_start); +PROVIDE (__bss2_end = __bss2_end); diff --git a/start.S b/start.S index 04fbc8c..5a91d89 100644 --- a/start.S +++ b/start.S @@ -5,11 +5,13 @@ .extern __got_end .extern __bss_start .extern __bss_end +.extern __bss2_start +.extern __bss2_end .extern __stack_addr .globl _start .globl debug_output -.globl panic -.globl delay + +.extern v_irq .section .init @@ -54,6 +56,22 @@ bss_loop: b bss_loop done_bss: + @ clear BSS2 + ldr r1, =__bss2_start + add r1, r4 + ldr r2, =__bss2_end + add r2, r4 + mov r3, #0 +bss2_loop: + @ check for the end + cmp r1, r2 + beq done_bss2 + @ clear the word and move on + str r3, [r1] + add r1, r1, #4 + b bss2_loop + +done_bss2: mov r0, #0x84 bl debug_output @ take the plunge @@ -79,8 +97,8 @@ v_data_abrt: v_reserved: b v_reserved -v_irq: - b v_irq +#v_irq: +# b v_irq v_fiq: b v_fiq @@ -97,30 +115,6 @@ debug_output: orr r2, r2, r0, LSL #16 @ store back str r2, [r3, #0xe0] - mov pc, lr - -panic: - mov r4, r0 -_panic: - mov r0, r4 - bl debug_output - ldr r0, =6175000 - bl delay - mov r0, #0x00 - bl debug_output - ldr r0, =6175000 - bl delay - b _panic - -@ the speed of this seems to decrease wildly with certain (non-)alignments -@ probably some prefetch buffer / cache / DRAM junk - .balign 64 -delay: - cmp r0, #0 - moveq pc, lr -1: - subs r0, r0, #1 - bne 1b - mov pc, lr + bx lr .pool diff --git a/start.h b/start.h index fe82649..9d37304 100644 --- a/start.h +++ b/start.h @@ -3,11 +3,6 @@ #include "types.h" -void delay(u32 delay); - -#define udelay(d) delay(247*(d)/10) - void debug_output(u8 byte); -void panic(u8 code); #endif diff --git a/types.h b/types.h index 78e16b3..d469da0 100644 --- a/types.h +++ b/types.h @@ -23,6 +23,20 @@ typedef volatile signed long long vs64; typedef s32 size_t; -#define NULL ((void *)0) +#define NULL ((void *)0) + +#define MEM2_BSS __attribute__ ((section (".bss.mem2"))) +#define MEM2_DATA __attribute__ ((section (".data.mem2"))) +#define MEM2_RODATA __attribute__ ((section (".rodata.mem2"))) +#define ALIGNED(x) __attribute__((aligned(x))) + +#define STACK_ALIGN(type, name, cnt, alignment) \ + u8 _al__##name[((sizeof(type)*(cnt)) + (alignment) + \ + (((sizeof(type)*(cnt))%(alignment)) > 0 ? ((alignment) - \ + ((sizeof(type)*(cnt))%(alignment))) : 0))]; \ + type *name = (type*)(((u32)(_al__##name)) + ((alignment) - (( \ + (u32)(_al__##name))&((alignment)-1)))) + + #endif diff --git a/utils.c b/utils.c index a72fb2e..ad9b07c 100644 --- a/utils.c +++ b/utils.c @@ -2,6 +2,8 @@ #include "utils.h" #include "gecko.h" #include "vsprintf.h" +#include "start.h" +#include "hollywood.h" static char ascii(char s) { if(s < 0x20) return '.'; @@ -38,3 +40,35 @@ int sprintf(char *str, const char *fmt, ...) return i; } +void udelay(u32 d) +{ + // should be good to max .2% error + u32 ticks = d * 19 / 10; + + if(ticks < 2) + ticks = 2; + + u32 now = read32(HW_TIMER); + + u32 then = now + ticks; + + if(then < now) { + while(read32(HW_TIMER) >= now); + now = read32(HW_TIMER); + } + + while(now < then) { + now = read32(HW_TIMER); + } +} + +void panic(u8 v) +{ + while(1) { + debug_output(v); + udelay(500000); + debug_output(0); + udelay(500000); + } +} + diff --git a/utils.h b/utils.h index cdf97b6..6757f2e 100644 --- a/utils.h +++ b/utils.h @@ -160,16 +160,6 @@ static inline u8 mask8(u32 addr, u8 clear, u8 set) return data; } -#define STACK_ALIGN(type, name, cnt, alignment) \ -u8 _al__##name[((sizeof(type)*(cnt)) + (alignment) + \ -(((sizeof(type)*(cnt))%(alignment)) > 0 ? ((alignment) - \ -((sizeof(type)*(cnt))%(alignment))) : 0))]; \ -type *name = (type*)(((u32)(_al__##name)) + ((alignment) - (( \ -(u32)(_al__##name))&((alignment)-1)))) - -#define ATTRIBUTE_ALIGN(v) __attribute__((aligned(v))) - - /* * These functions are guaranteed to copy by reading from src and writing to dst in -bit units * If size is not aligned, the remaining bytes are not copied @@ -183,5 +173,7 @@ void memcpy8(void *dst, void *src, u32 size); void hexdump(void *d, int len); int sprintf(char *str, const char *fmt, ...); +void udelay(u32 d); +void panic(u8 v); #endif