mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-24 12:19:21 +01:00
Interrupts, IPC, moar stuff
This commit is contained in:
parent
599839a7f9
commit
b80e7b74dd
8
Makefile
8
Makefile
@ -1,6 +1,6 @@
|
|||||||
include ../toolchain.rules
|
include ../toolchain.rules
|
||||||
|
|
||||||
CFLAGS = -mbig-endian -fomit-frame-pointer -Os -Wall -I.
|
CFLAGS = -mbig-endian -fomit-frame-pointer -Os -Wall -I.
|
||||||
ASFLAGS = -mbig-endian
|
ASFLAGS = -mbig-endian
|
||||||
LDFLAGS = -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,miniios.ld,-Map,miniios.map -n
|
LDFLAGS = -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,miniios.ld,-Map,miniios.map -n
|
||||||
LIBS = -lgcc
|
LIBS = -lgcc
|
||||||
@ -10,8 +10,8 @@ MAKEBIN = python ../makebin.py
|
|||||||
|
|
||||||
TARGET = miniios.bin
|
TARGET = miniios.bin
|
||||||
ELF = miniios.elf
|
ELF = miniios.elf
|
||||||
OBJECTS = start.o main.o vsprintf.o string.o gecko.o memory.o memory_asm.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
|
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)
|
$(TARGET) : $(ELF) $(ELFLOADER)
|
||||||
@echo "MAKEBIN $@"
|
@echo "MAKEBIN $@"
|
||||||
@ -23,7 +23,7 @@ $(ELF) : miniios.ld $(OBJECTS)
|
|||||||
|
|
||||||
%.o : %.S
|
%.o : %.S
|
||||||
@echo "AS $@"
|
@echo "AS $@"
|
||||||
@$(AS) $(ASFLAGS) -o $@ $<
|
@$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $<
|
||||||
|
|
||||||
%.o : %.c
|
%.o : %.c
|
||||||
@echo "CC $@"
|
@echo "CC $@"
|
||||||
|
2
diskio.c
2
diskio.c
@ -10,7 +10,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static sdhci_t sdhci;
|
static sdhci_t sdhci;
|
||||||
static u8 *buffer[512] __attribute__((aligned(32)));
|
static u8 buffer[512] MEM2_BSS ALIGNED(32);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Inidialize a Drive */
|
/* Inidialize a Drive */
|
||||||
|
@ -131,6 +131,8 @@
|
|||||||
// maybe a GPIO???
|
// maybe a GPIO???
|
||||||
#define HW_RESETS (HW_REG_BASE + 0x194)
|
#define HW_RESETS (HW_REG_BASE + 0x194)
|
||||||
|
|
||||||
|
#define HW_CLOCKS (HW_REG_BASE + 0x1b4)
|
||||||
|
|
||||||
#define HW_GPIO2OUT (HW_REG_BASE + 0x1c8)
|
#define HW_GPIO2OUT (HW_REG_BASE + 0x1c8)
|
||||||
#define HW_GPIO2DIR (HW_REG_BASE + 0x1cc)
|
#define HW_GPIO2DIR (HW_REG_BASE + 0x1cc)
|
||||||
#define HW_GPIO2IN (HW_REG_BASE + 0x1d0)
|
#define HW_GPIO2IN (HW_REG_BASE + 0x1d0)
|
||||||
|
29
ipcstruct.S
Normal file
29
ipcstruct.S
Normal file
@ -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
|
11
ipcstruct.h
Normal file
11
ipcstruct.h
Normal file
@ -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
|
81
irq.c
Normal file
81
irq.c
Normal file
@ -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<<irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_disable(u32 irq)
|
||||||
|
{
|
||||||
|
clear32(HW_IRQENABLE, 1<<irq);
|
||||||
|
}
|
40
irq.h
Normal file
40
irq.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef __IRQ_H__
|
||||||
|
#define __IRQ_H__
|
||||||
|
|
||||||
|
#define IRQ_TIMER 0
|
||||||
|
#define IRQ_NAND 1
|
||||||
|
#define IRQ_GPIO1B 10
|
||||||
|
#define IRQ_GPIO1 11
|
||||||
|
#define IRQ_RESET 17
|
||||||
|
#define IRQ_IPC 31
|
||||||
|
|
||||||
|
#define IRQF_TIMER (1<<IRQ_TIMER)
|
||||||
|
#define IRQF_NAND (1<<IRQ_NAND)
|
||||||
|
#define IRQF_GPIO1B (1<<IRQ_GPIO1B)
|
||||||
|
#define IRQF_GPIO1 (1<<IRQ_GPIO1)
|
||||||
|
#define IRQF_RESET (1<<IRQ_RESET)
|
||||||
|
#define IRQF_IPC (1<<IRQ_IPC)
|
||||||
|
|
||||||
|
#define IRQF_ALL ( \
|
||||||
|
IRQF_TIMER|IRQF_NAND|IRQF_GPIO1B|IRQF_GPIO1| \
|
||||||
|
IRQF_RESET|IRQF_IPC \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define CPSR_IRQDIS 0x80
|
||||||
|
#define CPSR_FIQDIS 0x40
|
||||||
|
|
||||||
|
#ifndef _LANGUAGE_ASSEMBLY
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
void irq_initialize(void);
|
||||||
|
void irq_shutdown(void);
|
||||||
|
|
||||||
|
void irq_enable(u32 irq);
|
||||||
|
void irq_disable(u32 irq);
|
||||||
|
|
||||||
|
u32 irq_kill(void);
|
||||||
|
void irq_restore(u32 cookie);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
46
irq_asm.S
Normal file
46
irq_asm.S
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "hollywood.h"
|
||||||
|
#include "irq.h"
|
||||||
|
|
||||||
|
.globl v_irq
|
||||||
|
.globl irq_setup_stack
|
||||||
|
.globl irq_kill
|
||||||
|
.globl irq_restore
|
||||||
|
.extern __irqstack_addr
|
||||||
|
.extern irq_handler
|
||||||
|
|
||||||
|
irq_setup_stack:
|
||||||
|
@ Switch to IRQ mode
|
||||||
|
mrs r0, cpsr
|
||||||
|
bic r1, r0, #0x1f
|
||||||
|
orr r1, #0x12
|
||||||
|
msr cpsr, r1
|
||||||
|
|
||||||
|
@ Setup interrupt stack
|
||||||
|
ldr sp, =__stack_addr
|
||||||
|
add sp, r4
|
||||||
|
|
||||||
|
@ Restore mode
|
||||||
|
msr cpsr, r0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
v_irq:
|
||||||
|
push {r0-r3, r9, r12, lr}
|
||||||
|
|
||||||
|
blx irq_handler
|
||||||
|
|
||||||
|
pop {r0-r3, r9, r12, lr}
|
||||||
|
subs pc, lr, #4
|
||||||
|
|
||||||
|
irq_kill:
|
||||||
|
mrs r1, cpsr
|
||||||
|
and r0, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||||
|
orr r1, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||||
|
msr cpsr, r1
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
irq_restore:
|
||||||
|
mrs r1, cpsr
|
||||||
|
bic r1, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||||
|
orr r1, r1, r0
|
||||||
|
msr cpsr, r1
|
||||||
|
bx lr
|
18
main.c
18
main.c
@ -10,6 +10,7 @@
|
|||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "powerpc_elf.h"
|
#include "powerpc_elf.h"
|
||||||
|
#include "irq.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 hdrsize;
|
u32 hdrsize;
|
||||||
@ -152,6 +153,15 @@ void *_main(void *base)
|
|||||||
gecko_printf("Error %d while trying to mount SD\n", fres);
|
gecko_printf("Error %d while trying to mount SD\n", fres);
|
||||||
panic2(0, PANIC_MOUNT);
|
panic2(0, PANIC_MOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irq_initialize();
|
||||||
|
irq_enable(IRQ_TIMER);
|
||||||
|
irq_enable(IRQ_NAND);
|
||||||
|
irq_enable(IRQ_GPIO1B);
|
||||||
|
irq_enable(IRQ_GPIO1);
|
||||||
|
irq_enable(IRQ_RESET);
|
||||||
|
irq_enable(IRQ_IPC);
|
||||||
|
gecko_puts("Interrupts initialized\n");
|
||||||
|
|
||||||
gecko_puts("Trying to boot:" PPC_BOOT_FILE "\n");
|
gecko_puts("Trying to boot:" PPC_BOOT_FILE "\n");
|
||||||
|
|
||||||
@ -180,7 +190,11 @@ void *_main(void *base)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *bootmii = patch_boot2(base, (((u64)tidh)<<32) | tidl);
|
||||||
|
|
||||||
|
gecko_puts("Shutting down interrupts\n");
|
||||||
|
irq_shutdown();
|
||||||
|
|
||||||
gecko_puts("Returning to BootMii...\n");
|
gecko_puts("Returning to BootMii...\n");
|
||||||
|
return bootmii;
|
||||||
return patch_boot2(base, (((u64)tidh)<<32) | tidl);
|
|
||||||
}
|
}
|
||||||
|
76
miniios.ld
76
miniios.ld
@ -3,35 +3,65 @@ OUTPUT_ARCH(arm)
|
|||||||
EXTERN(_start)
|
EXTERN(_start)
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
__base_addr = 0xffff0000;
|
__stack_size = 0x800;
|
||||||
|
__irqstack_size = 0x100;
|
||||||
|
|
||||||
__data_addr = 0x11000000;
|
MEMORY {
|
||||||
|
sram : ORIGIN = 0xffff0000, LENGTH = 64K
|
||||||
__stack_area = 0xfffe0000;
|
sram2 : ORIGIN = 0xfffe0000, LENGTH = 32K
|
||||||
|
mem2 : ORIGIN = 0x13f00000, LENGTH = 1M
|
||||||
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = __base_addr;
|
.rodata.ipc :
|
||||||
|
{
|
||||||
|
*(.rodata.ipc)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >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 :
|
||||||
{
|
{
|
||||||
*(.init)
|
*(.init)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
}
|
} >sram
|
||||||
|
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
|
*(.text*)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
*(.gnu.warning)
|
*(.gnu.warning)
|
||||||
*(.gnu.linkonce.t*)
|
*(.gnu.linkonce.t*)
|
||||||
*(.glue_7)
|
*(.glue_7)
|
||||||
*(.glue_7t)
|
*(.glue_7t)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
}
|
} >sram
|
||||||
|
|
||||||
__text_end = . ;
|
|
||||||
|
|
||||||
. = __data_addr;
|
|
||||||
|
|
||||||
.rodata :
|
.rodata :
|
||||||
{
|
{
|
||||||
@ -41,7 +71,7 @@ SECTIONS
|
|||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
*(.gnu.linkonce.r*)
|
*(.gnu.linkonce.r*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
}
|
} >sram2
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
@ -49,7 +79,7 @@ SECTIONS
|
|||||||
*(.data.*)
|
*(.data.*)
|
||||||
*(.gnu.linkonce.d*)
|
*(.gnu.linkonce.d*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
}
|
} >sram2
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
@ -61,23 +91,27 @@ SECTIONS
|
|||||||
*(COMMON)
|
*(COMMON)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
__bss_end = . ;
|
__bss_end = . ;
|
||||||
}
|
} >sram2
|
||||||
|
|
||||||
. = __stack_area;
|
|
||||||
.stack :
|
.stack :
|
||||||
{
|
{
|
||||||
__stack_end = .;
|
__stack_end = .;
|
||||||
. += 0x800;
|
. = . +__stack_size;
|
||||||
LONG(0);
|
|
||||||
. = ALIGN(64);
|
. = ALIGN(64);
|
||||||
__stack_addr = .;
|
__stack_addr = .;
|
||||||
}
|
__irqstack_end = .;
|
||||||
|
. = . +__irqstack_size;
|
||||||
__end = .;
|
. = ALIGN(64);
|
||||||
|
__irqstack_addr = .;
|
||||||
|
} >sram2
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PROVIDE (__stack_end = __stack_end);
|
PROVIDE (__stack_end = __stack_end);
|
||||||
PROVIDE (__stack_addr = __stack_addr);
|
PROVIDE (__stack_addr = __stack_addr);
|
||||||
|
PROVIDE (__irqstack_end = __irqstack_end);
|
||||||
|
PROVIDE (__irqstack_addr = __irqstack_addr);
|
||||||
PROVIDE (__bss_start = __bss_start);
|
PROVIDE (__bss_start = __bss_start);
|
||||||
PROVIDE (__bss_end = __bss_end);
|
PROVIDE (__bss_end = __bss_end);
|
||||||
|
PROVIDE (__bss2_start = __bss2_start);
|
||||||
|
PROVIDE (__bss2_end = __bss2_end);
|
||||||
|
52
start.S
52
start.S
@ -5,11 +5,13 @@
|
|||||||
.extern __got_end
|
.extern __got_end
|
||||||
.extern __bss_start
|
.extern __bss_start
|
||||||
.extern __bss_end
|
.extern __bss_end
|
||||||
|
.extern __bss2_start
|
||||||
|
.extern __bss2_end
|
||||||
.extern __stack_addr
|
.extern __stack_addr
|
||||||
.globl _start
|
.globl _start
|
||||||
.globl debug_output
|
.globl debug_output
|
||||||
.globl panic
|
|
||||||
.globl delay
|
.extern v_irq
|
||||||
|
|
||||||
.section .init
|
.section .init
|
||||||
|
|
||||||
@ -54,6 +56,22 @@ bss_loop:
|
|||||||
b bss_loop
|
b bss_loop
|
||||||
|
|
||||||
done_bss:
|
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
|
mov r0, #0x84
|
||||||
bl debug_output
|
bl debug_output
|
||||||
@ take the plunge
|
@ take the plunge
|
||||||
@ -79,8 +97,8 @@ v_data_abrt:
|
|||||||
v_reserved:
|
v_reserved:
|
||||||
b v_reserved
|
b v_reserved
|
||||||
|
|
||||||
v_irq:
|
#v_irq:
|
||||||
b v_irq
|
# b v_irq
|
||||||
|
|
||||||
v_fiq:
|
v_fiq:
|
||||||
b v_fiq
|
b v_fiq
|
||||||
@ -97,30 +115,6 @@ debug_output:
|
|||||||
orr r2, r2, r0, LSL #16
|
orr r2, r2, r0, LSL #16
|
||||||
@ store back
|
@ store back
|
||||||
str r2, [r3, #0xe0]
|
str r2, [r3, #0xe0]
|
||||||
mov pc, lr
|
bx 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
|
|
||||||
|
|
||||||
.pool
|
.pool
|
||||||
|
5
start.h
5
start.h
@ -3,11 +3,6 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void delay(u32 delay);
|
|
||||||
|
|
||||||
#define udelay(d) delay(247*(d)/10)
|
|
||||||
|
|
||||||
void debug_output(u8 byte);
|
void debug_output(u8 byte);
|
||||||
void panic(u8 code);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
16
types.h
16
types.h
@ -23,6 +23,20 @@ typedef volatile signed long long vs64;
|
|||||||
|
|
||||||
typedef s32 size_t;
|
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
|
#endif
|
||||||
|
34
utils.c
34
utils.c
@ -2,6 +2,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "gecko.h"
|
#include "gecko.h"
|
||||||
#include "vsprintf.h"
|
#include "vsprintf.h"
|
||||||
|
#include "start.h"
|
||||||
|
#include "hollywood.h"
|
||||||
|
|
||||||
static char ascii(char s) {
|
static char ascii(char s) {
|
||||||
if(s < 0x20) return '.';
|
if(s < 0x20) return '.';
|
||||||
@ -38,3 +40,35 @@ int sprintf(char *str, const char *fmt, ...)
|
|||||||
return i;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
12
utils.h
12
utils.h
@ -160,16 +160,6 @@ static inline u8 mask8(u32 addr, u8 clear, u8 set)
|
|||||||
return data;
|
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 <n>-bit units
|
* These functions are guaranteed to copy by reading from src and writing to dst in <n>-bit units
|
||||||
* If size is not aligned, the remaining bytes are not copied
|
* 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);
|
void hexdump(void *d, int len);
|
||||||
int sprintf(char *str, const char *fmt, ...);
|
int sprintf(char *str, const char *fmt, ...);
|
||||||
|
void udelay(u32 d);
|
||||||
|
void panic(u8 v);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user