diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/system.c | 135 |
1 files changed, 66 insertions, 69 deletions
diff --git a/firmware/system.c b/firmware/system.c index fe2446e1c3..81d5ee9202 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -688,11 +688,13 @@ static const char* const irqname[] = { | |||
688 | "\n\t.set\t_" #name ",_UIE" #number \ | 688 | "\n\t.set\t_" #name ",_UIE" #number \ |
689 | "\n\t.long\t_" #name "\n" | 689 | "\n\t.long\t_" #name "\n" |
690 | 690 | ||
691 | asm ( | ||
692 | |||
691 | /* Vector table. | 693 | /* Vector table. |
692 | * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols | 694 | * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols |
693 | * defined in an asm block -- silly. | 695 | * defined in an asm block -- silly. |
694 | * Reset vectors (0..3) are handled in crt0.S */ | 696 | * Reset vectors (0..3) are handled in crt0.S */ |
695 | asm ( | 697 | |
696 | ".section\t.vectors,\"aw\",@progbits\n" | 698 | ".section\t.vectors,\"aw\",@progbits\n" |
697 | DEFAULT_INTERRUPT (GII, 4) | 699 | DEFAULT_INTERRUPT (GII, 4) |
698 | RESERVE_INTERRUPT ( 5) | 700 | RESERVE_INTERRUPT ( 5) |
@@ -800,76 +802,11 @@ asm ( | |||
800 | DEFAULT_INTERRUPT (TEI1, 107) | 802 | DEFAULT_INTERRUPT (TEI1, 107) |
801 | RESERVE_INTERRUPT ( 108) | 803 | RESERVE_INTERRUPT ( 108) |
802 | DEFAULT_INTERRUPT (ADITI, 109) | 804 | DEFAULT_INTERRUPT (ADITI, 109) |
803 | "\t.text\n" | ||
804 | ); | ||
805 | |||
806 | extern void UIE0(void); /* needed for calculating the UIE number */ | ||
807 | |||
808 | void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | ||
809 | { | ||
810 | #if CONFIG_LED == LED_REAL | ||
811 | bool state = true; | ||
812 | #endif | ||
813 | unsigned int n; | ||
814 | char str[32]; | ||
815 | |||
816 | asm volatile ("sts\tpr,%0" : "=r"(n)); | ||
817 | |||
818 | /* clear screen */ | ||
819 | lcd_clear_display (); | ||
820 | #ifdef HAVE_LCD_BITMAP | ||
821 | lcd_setfont(FONT_SYSFIXED); | ||
822 | #endif | ||
823 | /* output exception */ | ||
824 | n = (n - (unsigned)UIE0 - 4)>>2; /* get exception or interrupt number */ | ||
825 | snprintf(str,sizeof(str),"I%02x:%s",n,irqname[n]); | ||
826 | lcd_puts(0,0,str); | ||
827 | snprintf(str,sizeof(str),"at %08x",pc); | ||
828 | lcd_puts(0,1,str); | ||
829 | |||
830 | #ifdef HAVE_LCD_BITMAP | ||
831 | lcd_update (); | ||
832 | #endif | ||
833 | |||
834 | while (1) | ||
835 | { | ||
836 | #if CONFIG_LED == LED_REAL | ||
837 | volatile int i; | ||
838 | led (state); | ||
839 | state = !state; | ||
840 | |||
841 | for (i = 0; i < 240000; ++i); | ||
842 | #endif | ||
843 | |||
844 | /* try to restart firmware if ON is pressed */ | ||
845 | #if CONFIG_KEYPAD == PLAYER_PAD | ||
846 | if (!(PADRL & 0x20)) | ||
847 | #elif CONFIG_KEYPAD == RECORDER_PAD | ||
848 | #ifdef HAVE_FMADC | ||
849 | if (!(PCDR & 0x0008)) | ||
850 | #else | ||
851 | if (!(PBDRH & 0x01)) | ||
852 | #endif | ||
853 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
854 | if (!(PCDR & 0x0008)) | ||
855 | #endif | ||
856 | { | ||
857 | /* enable the watchguard timer, but don't service it */ | ||
858 | RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ | ||
859 | TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ | ||
860 | } | ||
861 | } | ||
862 | } | ||
863 | 805 | ||
864 | /* UIE# block. | 806 | /* UIE# block. |
865 | * Keep directly after UIE() to let it go into the same section as UIE(). | 807 | * Must go into the same section as the UIE() handler */ |
866 | * Otherwise there will be displacement overflows with sectioned compilation | 808 | |
867 | * (bootbox) */ | 809 | "\t.text\n" |
868 | asm ( | ||
869 | "_UIE0:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | ||
870 | "_UIE1:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | ||
871 | "_UIE2:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | ||
872 | "_UIE3:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | ||
873 | "_UIE4:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 810 | "_UIE4:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
874 | "_UIE5:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 811 | "_UIE5:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
875 | "_UIE6:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 812 | "_UIE6:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
@@ -976,8 +913,68 @@ asm ( | |||
976 | "_UIE107:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 913 | "_UIE107:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
977 | "_UIE108:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 914 | "_UIE108:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
978 | "_UIE109:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" | 915 | "_UIE109:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n" |
916 | |||
979 | ); | 917 | ); |
980 | 918 | ||
919 | extern void UIE4(void); /* needed for calculating the UIE number */ | ||
920 | |||
921 | void UIE (unsigned int pc) __attribute__((section(".text"))); | ||
922 | void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */ | ||
923 | { | ||
924 | #if CONFIG_LED == LED_REAL | ||
925 | bool state = true; | ||
926 | #endif | ||
927 | unsigned int n; | ||
928 | char str[32]; | ||
929 | |||
930 | asm volatile ("sts\tpr,%0" : "=r"(n)); | ||
931 | |||
932 | /* clear screen */ | ||
933 | lcd_clear_display (); | ||
934 | #ifdef HAVE_LCD_BITMAP | ||
935 | lcd_setfont(FONT_SYSFIXED); | ||
936 | #endif | ||
937 | /* output exception */ | ||
938 | n = (n - (unsigned)UIE4 - 20)>>2; /* get exception or interrupt number */ | ||
939 | snprintf(str,sizeof(str),"I%02x:%s",n,irqname[n]); | ||
940 | lcd_puts(0,0,str); | ||
941 | snprintf(str,sizeof(str),"at %08x",pc); | ||
942 | lcd_puts(0,1,str); | ||
943 | |||
944 | #ifdef HAVE_LCD_BITMAP | ||
945 | lcd_update (); | ||
946 | #endif | ||
947 | |||
948 | while (1) | ||
949 | { | ||
950 | #if CONFIG_LED == LED_REAL | ||
951 | volatile int i; | ||
952 | led (state); | ||
953 | state = !state; | ||
954 | |||
955 | for (i = 0; i < 240000; ++i); | ||
956 | #endif | ||
957 | |||
958 | /* try to restart firmware if ON is pressed */ | ||
959 | #if CONFIG_KEYPAD == PLAYER_PAD | ||
960 | if (!(PADRL & 0x20)) | ||
961 | #elif CONFIG_KEYPAD == RECORDER_PAD | ||
962 | #ifdef HAVE_FMADC | ||
963 | if (!(PCDR & 0x0008)) | ||
964 | #else | ||
965 | if (!(PBDRH & 0x01)) | ||
966 | #endif | ||
967 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
968 | if (!(PCDR & 0x0008)) | ||
969 | #endif | ||
970 | { | ||
971 | /* enable the watchguard timer, but don't service it */ | ||
972 | RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */ | ||
973 | TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */ | ||
974 | } | ||
975 | } | ||
976 | } | ||
977 | |||
981 | void system_init(void) | 978 | void system_init(void) |
982 | { | 979 | { |
983 | /* Disable all interrupts */ | 980 | /* Disable all interrupts */ |