# HG changeset patch # User Paul Boddie # Date 1494761353 -7200 # Node ID e6fa4e9b4e4f86e6d2356a9fa943024b1020e164 # Parent c2f73f8a609ce5097b7d8bce6e0ef48b7689ea7f Introduced interrupt and exception initialisation fixes plus a revised state machine for signal generation and use of two output compare units for the sync pulses. This does generate a signal but refinement is needed. Moved framebuffer initialisation to a point where it does not cause an exception for some undiagnosed reason. diff -r c2f73f8a609c -r e6fa4e9b4e4f mips.h --- a/mips.h Thu May 11 00:23:47 2017 +0200 +++ b/mips.h Sun May 14 13:29:13 2017 +0200 @@ -10,7 +10,9 @@ #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_WIRED $6 +#define CP0_COUNT $9 #define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 #define CP0_STATUS $12 #define CP0_INTCTL $12, 1 #define CP0_CAUSE $13 @@ -18,8 +20,10 @@ #define CP0_EBASE $15, 1 #define CP0_CONFIG $16 #define CP0_WATCHLO $18 +#define CP0_DEBUG $23 #define CP0_TAGLO $28 #define CP0_TAGHI $29 +#define CP0_ERROREPC $30, 0 #define STATUS_CP0 0x10000000 #define STATUS_BEV 0x00400000 @@ -35,6 +39,8 @@ #define INTCTL_MASK 0x000003e0 +#define DEBUG_DM 0x40000000 + #define TLB_CACHED 0x00000018 #define TLB_UNCACHED 0x00000010 #define TLB_DIRTY 0x00000004 diff -r c2f73f8a609c -r e6fa4e9b4e4f pic32.h --- a/pic32.h Thu May 11 00:23:47 2017 +0200 +++ b/pic32.h Sun May 14 13:29:13 2017 +0200 @@ -14,6 +14,9 @@ #define OC2CON 0xBF803200 #define OC2R 0xBF803210 #define OC2RS 0xBF803220 +#define OC3CON 0xBF803400 +#define OC3R 0xBF803410 +#define OC3RS 0xBF803420 #define T1CON 0xBF800600 #define TMR1 0xBF800610 @@ -36,6 +39,7 @@ #define RPB4R 0xBF80FB3C #define RPB5R 0xBF80FB40 +#define RPB10R 0xBF80FB54 #define INTCON 0xBF881000 #define IFS0 0xBF881030 @@ -49,6 +53,8 @@ #define IPC10 0xBF881130 #define BMXCON 0xBF882000 +#define BMXDKPBA 0xBF882010 +#define BMXDUDBA 0xBF882020 #define BMXDRMSZ 0xBF882040 #define DMACON 0xBF883000 diff -r c2f73f8a609c -r e6fa4e9b4e4f vga.S --- a/vga.S Thu May 11 00:23:47 2017 +0200 +++ b/vga.S Sun May 14 13:29:13 2017 +0200 @@ -20,14 +20,21 @@ #include "mips.h" #include "pic32.h" -#define HFREQ_LIMIT 627 /* 20MHz cycles */ -#define HSYNC_LIMIT 16 /* bytes or pixels */ -#define LINE_LIMIT 160 /* bytes or pixels */ +#define LINE_LENGTH 160 /* pixels */ + +#define HFREQ_LIMIT 1254 /* 40MHz cycles */ +#define LINE_LIMIT 960 /* 40MHz cycles (3 per byte/pixel) */ +#define HSYNC_LIMIT 96 /* 40MHz cycles (3 per byte/pixel) */ -#define VSYNC_START 1 /* horizontal lines, front porch end */ -#define VISIBLE_START 4 /* horizontal lines */ -#define VBP_START 516 /* horizontal lines, back porch start */ -#define VBP_END 531 /* horizontal lines, back porch end */ +#define HSYNC_START LINE_LIMIT +#define HSYNC_END (HSYNC_START + HSYNC_LIMIT) + +#define VISIBLE_START 15 /* horizontal lines, back porch end */ +#define VFP_START 527 /* horizontal lines, front porch start */ +#define VSYNC_START 529 /* horizontal lines, front porch end */ +#define VSYNC_END 531 /* horizontal lines, back porch start */ + +#define SCREEN_SIZE (40 * 1024) /* Disable JTAG functionality on pins. */ @@ -36,23 +43,31 @@ /* Set the oscillator to be the FRC oscillator with PLL, with peripheral clock -divided by 1, HS oscillator mode selected (for PLL), and FRCDIV+PLL selected. -With a system clock of 20MHz, the peripheral clock is therefore 20MHz. +divided by 1, and FRCDIV+PLL selected. + +The system clock and peripheral clock are therefore the same. The watchdog timer (FWDTEN) is also disabled. + +The secondary oscillator pin (FSOSCEN) is disabled to avoid pin conflicts with +RPB4. */ .section .devcfg1, "a" -.word 0xff7fcff9 /* DEVCFG1<23> = FWDTEN = 0; DEVCFG1<13:12> = FPBDIV<2:0> = 0; DEVCFG1<2:0> = FNOSC<2:0> = 001 */ +.word 0xff7fcfd9 /* DEVCFG1<23> = FWDTEN = 0; DEVCFG1<13:12> = FPBDIV<2:0> = 0; + DEVCFG1<5> = FSOSCEN = 0; DEVCFG1<2:0> = FNOSC<2:0> = 001 */ /* Set the FRC oscillator PLL function with an input division of 4, an output division of 2, a multiplication of 20, yielding a multiplication of 2.5. -This should take the FRC at 8MHz and produce a system clock of 20MHz. + +The FRC is apparently at 16MHz and this produces a system clock of 40MHz. */ .section .devcfg2, "a" -.word 0xfff9ffdb /* DEVCFG2<18:16> = FPLLODIV<2:0> = 1; DEVCFG2<6:4> = FPLLMUL<2:0> = 101; DEVCFG2<2:0> = FPLLIDIV<2:0> = 011 */ +.word 0xfff9ffdb /* DEVCFG2<18:16> = FPLLODIV<2:0> = 001; + DEVCFG2<6:4> = FPLLMUL<2:0> = 101; + DEVCFG2<2:0> = FPLLIDIV<2:0> = 011 */ .text .globl _start @@ -83,6 +98,11 @@ li $v1, KSEG0_BASE addu $sp, $v0, $v1 /* sp = KSEG0_BASE + RAM size */ + /* Initialise framebuffer. */ + + jal init_framebuffer + nop + /* Initialise the globals pointer. */ lui $gp, %hi(_GLOBAL_OFFSET_TABLE_) @@ -116,14 +136,9 @@ jal init_dma nop - /* Initialise OC2. */ + /* Initialise OC3 and OC2. */ - jal init_oc2 - nop - - /* Initialise framebuffer. */ - - jal init_framebuffer + jal init_oc nop /* Enable interrupts and loop. */ @@ -134,14 +149,24 @@ jal handle_error_level nop + /* Set initial sync conditions. */ + + la $t0, PORTB + li $t1, (1 << 5) /* PORTB<5> = RB5 */ + sw $t1, SET($t0) + + la $t0, PORTB + li $t1, (1 << 10) /* PORTB<10> = RB10 */ + sw $t1, SET($t0) + /* Main program. */ - li $a1, 20000000 /* counter = 20000000 */ + li $a1, 5000000 /* counter = 5000000 */ /* Initialise the display state. */ li $s0, 0 /* line counter */ - la $s1, vfp_active /* current event */ + la $s1, vbp_active /* current event */ move $s2, $zero /* line address */ /* Monitoring loop. */ @@ -150,10 +175,10 @@ bnez $a1, loop /* until counter == 0 */ nop - li $a1, 20000000 /* counter = 20000000 */ + li $a1, 5000000 /* counter = 5000000 */ la $t0, PORTB - li $t1, (1 << 10) /* PORTB<10> = RB10 */ + li $t1, (1 << 11) /* PORTB<11> = RB11 */ sw $t1, INV($t0) _next: @@ -182,274 +207,11 @@ la $v0, TRISB sw $zero, 0($v0) - jr $ra - nop - - - -/* Interrupt servicing. */ - -.org 0x200 - -interrupt_handler: - - /* Check for a timer interrupt condition. */ - - la $v0, IFS0 - lw $v1, 0($v0) - andi $v1, $v1, (1 << 9) /* T2IF */ - beqz $v1, irq_pmp - nop - - /* Increment the line counter. */ - - addiu $s0, $s0, 1 - - /* Jump to the event handler. */ - - jalr $s1 - nop - -irq_clear_timer: - - /* Clear the timer interrupt condition. */ - - la $v0, IFS0 - li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */ - sw $v1, CLR($v0) - -irq_pmp: - - /* Check for a PMP interrupt condition. */ - - la $v0, IFS1 - lw $v1, 0($v0) - li $t8, (1 << 16) /* PMPIF */ - and $v1, $v1, $t8 - beqz $v1, irq_dma - nop - -irq_clear_pmp: - - /* Clear the PMP interrupt condition. */ - - la $v0, IFS1 - li $v1, (1 << 16) /* IFS1<16> = PMPIF = 0 */ - sw $v1, CLR($v0) - -irq_dma: - - /* Check for a DMA interrupt condition. */ - - la $v0, IFS1 - lw $v1, 0($v0) - li $t8, (1 << 28) /* DMA0IF */ - and $v1, $v1, $t8 - beqz $v1, irq_exit - nop - - /* Test the block transfer completion interrupt flag. */ - - la $v0, DCH0INT - lw $v1, 0($v0) - andi $v1, $v1, (1 << 3) /* CHBCIF */ - beqz $v1, irq_clear_dma - nop - - /* Clear the block transfer completion interrupt flag. */ - - li $v1, (1 << 3) /* CHBCIF = 0 */ - sw $v1, CLR($v0) - - /* - Update the line data address if the line counter (referring to the - next line) is even. - */ - - andi $t8, $s0, 1 - bnez $t8, irq_clear_dma - nop - - /* Reference the next line and update the DMA source address. */ - - addiu $s2, $s2, LINE_LIMIT - la $v0, DCH0SSA - sw $s2, 0($v0) - -irq_clear_dma: - - /* Clear the DMA interrupt condition. */ - - la $v0, IFS1 - li $v1, (1 << 28) /* IFS1<28> = DMA0IF = 0 */ - sw $v1, CLR($v0) - -irq_exit: - eret - nop - - - -/* Utilities. */ - -handle_error_level: - mfc0 $t3, CP0_STATUS - li $t4, ~(STATUS_ERL | STATUS_EXL) - and $t3, $t3, $t4 - mtc0 $t3, CP0_STATUS - jr $ra - nop - -enable_interrupts: - mfc0 $t3, CP0_STATUS - nop - ori $t3, $t3, STATUS_IRQ | STATUS_IE - mtc0 $t3, CP0_STATUS - jr $ra - nop - -init_interrupts: - mfc0 $t3, CP0_STATUS - li $t4, ~STATUS_BEV - and $t3, $t3, $t4 - mtc0 $t3, CP0_STATUS /* CP0_STATUS &= ~STATUS_BEV (use non-bootloader vectors) */ + la $v0, PORTA + sw $zero, 0($v0) + la $v0, PORTB + sw $zero, 0($v0) - la $t3, _start - mtc0 $t3, CP0_EBASE /* EBASE = _start */ - - li $t3, CAUSE_IV /* IV = 1 (use EBASE+0x200 for interrupts) */ - mtc0 $t3, CP0_CAUSE - - jr $ra - nop - - - -/* Event routines. */ - -/* Start of, and within, the vertical front porch. */ - -vfp_start: - /* Clear vsync. */ - - la $v0, PORTB - la $v1, (1 << 11) /* PORTB<11> = RB11 */ - sw $v1, CLR($v0) - - /* Enter the active region. */ - - la $s1, vfp_active - -vfp_active: - /* Test for vsync. */ - - subu $v0, $s0, VSYNC_START - bnez $v0, _vfp_active_ret - nop - - /* Start the vsync region. */ - - la $s1, vsync_start - -_vfp_active_ret: - jr $ra - nop - - - -/* Start of, and within, vsync. */ - -vsync_start: - /* Set vsync. */ - - la $v0, PORTB - la $v1, (1 << 11) /* PORTB<11> = RB11 */ - sw $v1, SET($v0) - - /* Enter the active region. */ - - la $s1, vsync_active - -vsync_active: - /* Test for visible region. */ - - subu $v0, $s0, VISIBLE_START - bnez $v0, _vsync_active_ret - nop - - /* Start the visible region. */ - - la $s1, visible_start - - /* Enable OC2 for the next line. */ - - la $v0, OC2CON - li $v1, (1 << 15) - sw $v1, SET($v0) - - /* Set the start address for line data. */ - - move $s2, $zero - la $v0, DCH0SSA - sw $s2, 0($v0) - -_vsync_active_ret: - jr $ra - nop - - - -/* Start of, and within, the visible period. */ - -visible_start: - /* Clear vsync. */ - - la $v0, PORTB - la $v1, (1 << 11) /* PORTB<11> = RB11 */ - sw $v1, CLR($v0) - - /* Enter the active region. */ - - la $s1, visible_active - -visible_active: - /* Test for back porch. */ - - subu $v0, $s0, VBP_START - bnez $v0, _visible_active_ret - nop - - /* Start the back porch. */ - - la $s1, vbp_active - - /* Disable OC2 for the next line. */ - - la $v0, OC2CON - li $v1, (1 << 15) - sw $v1, CLR($v0) - -_visible_active_ret: - jr $ra - nop - - - -/* Within the vertical back porch. */ - -vbp_active: - /* Test for front porch. */ - - subu $v0, $s0, VBP_END - bnez $v0, _vbp_active_ret - nop - - /* Start the front porch. */ - - li $s0, 0 - la $s1, vfp_start - -_vbp_active_ret: jr $ra nop @@ -504,14 +266,49 @@ /* Output compare initialisation. -Timer2 will be used to trigger two events: one initiating the hsync pulse, and -one terminating the pulse. Upon the termination of the pulse, an interrupt -condition will cause the line data to be transferred using DMA. +Timer2 will be used to trigger two events using OC3: one initiating the hsync +pulse, and one terminating the pulse. The pulse should appear after the line +data has been transferred using DMA, but this is achieved by just choosing +suitable start and end values. +Using OC2, Timer 2 triggers a level shifting event and OC2 is reconfigured to +reverse the level at a later point. */ -init_oc2: - /* Disable OC interrupts. */ +init_oc: + /* Disable OC3 interrupts. */ + + la $v0, IEC0 + li $v1, (1 << 17) /* IEC0<17> = OC3IE = 0 */ + sw $v1, CLR($v0) + + la $v0, IFS0 + li $v1, (1 << 17) /* IFS0<17> = OC3IF = 0 */ + sw $v1, CLR($v0) + + /* Initialise OC3. */ + + la $v0, OC3CON + li $v1, 0b101 /* OC3CON<2:0> = OCM<2:0> = 101 (dual compare, continuous pulse) */ + sw $v1, 0($v0) + + /* Pulse start and end. */ + + la $v0, OC3R + li $v1, HSYNC_END /* HSYNC_START for positive polarity */ + sw $v1, 0($v0) + + la $v0, OC3RS + li $v1, HSYNC_START /* HSYNC_END for positive polarity */ + sw $v1, 0($v0) + + /* OC3 is enabled. */ + + la $v0, OC3CON + li $v1, (1 << 15) + sw $v1, SET($v0) + + /* Disable OC2 interrupts. */ la $v0, IEC0 li $v1, (1 << 12) /* IEC0<12> = OC2IE = 0 */ @@ -524,26 +321,20 @@ /* Initialise OC2. */ la $v0, OC2CON - li $v1, 0b101 /* OC2CON<2:0> = OCM<2:0> = 101 (dual compare, continuous pulse) */ + li $v1, 0b010 /* OC2CON<2:0> = OCM<2:0> = 010 (single compare, output driven low) */ sw $v1, 0($v0) - /* Set hsync start and end. */ + /* Set pulse position. */ la $v0, OC2R - li $v1, 16 - sw $v1, 0($v0) + sw $zero, 0($v0) - la $v0, OC2RS - li $v1, 32 - sw $v1, 0($v0) - - /* OC2 is enabled elsewhere when it needs to operate. */ + /* Enable OC2 later. */ jr $ra nop - init_oc_pins: /* Unlock the configuration register bits. */ @@ -559,6 +350,12 @@ li $v1, (1 << 13) /* IOLOCK = 0 */ sw $v1, CLR($v0) + /* Map OC3 to RPB10. */ + + la $v0, RPB10R + li $v1, 0b0101 /* RPB10R<3:0> = 0101 (OC3) */ + sw $v1, 0($v0) + /* Map OC2 to RPB5. */ la $v0, RPB5R @@ -637,9 +434,9 @@ /* Direct Memory Access initialisation. -Write 160 pixels to the PMP for the line data. This is initiated by an output -compare interrupt. Upon completion of the transfer, a DMA interrupt initiates -the address update routine, changing the source address of the DMA channel. +Write 160 pixels to the PMP for the line data. This is initiated by a timer +interrupt. Upon completion of the transfer, a DMA interrupt initiates the +address update routine, changing the source address of the DMA channel. */ init_dma: @@ -682,20 +479,20 @@ /* Initiate channel transfers when the initiating interrupt condition occurs: - DCHxECON<15:8> = CHSIRQ<7:0> = output compare 2 interrupt + DCHxECON<15:8> = CHSIRQ<7:0> = timer 2 interrupt */ la $v0, DCH0ECON - li $v1, (12 << 8) | (1 << 4) + li $v1, (9 << 8) | (1 << 4) sw $v1, 0($v0) /* The line channel has a cell size of 160 bytes: - DCHxCSIZ<15:0> = CHCSIZ<15:0> = LINE_LIMIT + DCHxCSIZ<15:0> = CHCSIZ<15:0> = LINE_LENGTH */ la $v0, DCH0CSIZ - li $v1, LINE_LIMIT + li $v1, LINE_LENGTH sw $v1, 0($v0) /* @@ -704,7 +501,7 @@ */ la $v0, DCH0SSIZ - li $v1, LINE_LIMIT + li $v1, LINE_LENGTH sw $v1, 0($v0) /* @@ -756,7 +553,7 @@ la $v0, IEC1 li $v1, (1 << 28) /* IEC1<28> = DMA0IE = 1 */ - /* sw $v1, SET($v0) */ + sw $v1, SET($v0) /* Enable channels. */ @@ -773,8 +570,8 @@ init_framebuffer: li $v0, KSEG0_BASE - li $t8, 40 * 1024 - li $v1, 0xff + li $t8, SCREEN_SIZE + li $v1, 0xff031ce0 _init_fb_loop: sw $v1, 0($v0) @@ -785,3 +582,263 @@ jr $ra nop + + + +/* Utilities. */ + +handle_error_level: + mfc0 $t3, CP0_STATUS + li $t4, ~(STATUS_ERL | STATUS_EXL) + and $t3, $t3, $t4 + mtc0 $t3, CP0_STATUS + jr $ra + nop + +enable_interrupts: + mfc0 $t3, CP0_STATUS + li $t4, ~STATUS_IRQ /* Clear interrupt priority bits. */ + and $t3, $t3, $t4 + li $t4, ~STATUS_BEV /* CP0_STATUS &= ~STATUS_BEV (use non-bootloader vectors) */ + and $t3, $t3, $t4 + ori $t3, $t3, STATUS_IE + mtc0 $t3, CP0_STATUS + jr $ra + nop + +init_interrupts: + mfc0 $t3, CP0_DEBUG + li $t4, ~DEBUG_DM + and $t3, $t3, $t4 + mtc0 $t3, CP0_DEBUG + + mfc0 $t3, CP0_STATUS + li $t4, STATUS_BEV + or $t3, $t3, $t4 + mtc0 $t3, CP0_STATUS + + la $t3, exception_handler + mtc0 $t3, CP0_EBASE /* EBASE = exception_handler */ + + li $t3, 0x20 /* Must be non-zero or the CPU gets upset */ + mtc0 $t3, CP0_INTCTL + + li $t3, CAUSE_IV /* IV = 1 (use EBASE+0x200 for interrupts) */ + mtc0 $t3, CP0_CAUSE + + /* Multiple vector... + la $t3, INTCON + li $t4, (1 << 12) + sw $t4, SET($t3) */ + + jr $ra + nop + + + +/* Exception servicing. */ + +.section .flash, "a" + +/* Exception servicing. */ + +exception_handler: + li $t8, 2500000 +exc_loop: + addiu $t8, $t8, -1 + bnez $t8, exc_loop + nop + la $v0, PORTB + li $v1, (1 << 11) /* PORTB<11> = RB11 */ + sw $v1, INV($v0) + j exception_handler + nop + + + +/* Interrupt servicing. */ + +.org 0x200 + +interrupt_handler: + + /* Check for a timer interrupt condition. */ + + la $v0, IFS0 + lw $v1, 0($v0) + andi $v1, $v1, (1 << 9) /* T2IF */ + beqz $v1, irq_dma + nop + + /* Increment the line counter. */ + + addiu $s0, $s0, 1 + + /* Jump to the event handler. */ + + jalr $s1 + nop + +irq_clear_timer: + + /* Clear the timer interrupt condition. */ + + la $v0, IFS0 + li $v1, (1 << 9) /* IFS0<9> = T2IF = 0 */ + sw $v1, CLR($v0) + +irq_dma: + + /* Check for a DMA interrupt condition. */ + + la $v0, IFS1 + lw $v1, 0($v0) + li $t8, (1 << 28) /* DMA0IF */ + and $v1, $v1, $t8 + beqz $v1, irq_exit + nop + + /* Test the block transfer completion interrupt flag. */ + + la $v0, DCH0INT + lw $v1, 0($v0) + andi $v1, $v1, (1 << 3) /* CHBCIF */ + beqz $v1, irq_clear_dma + nop + + /* Clear the block transfer completion interrupt flag. */ + + li $v1, (1 << 3) /* CHBCIF = 0 */ + sw $v1, CLR($v0) + + /* + Update the line data address if the line counter (referring to the + next line) is even. + */ + + andi $t8, $s0, 1 + bnez $t8, irq_clear_dma + nop + + /* Reference the next line and update the DMA source address. */ + + addiu $s2, $s2, LINE_LENGTH + + /* Test for wraparound. */ + + li $t8, SCREEN_SIZE + sltu $t8, $s2, $t8 + bnez $t8, irq_dma_update + nop + + /* Reset the source address. */ + + move $s2, $zero + +irq_dma_update: + + la $v0, DCH0SSA + sw $s2, 0($v0) + +irq_clear_dma: + + /* Clear the DMA interrupt condition. */ + + la $v0, IFS1 + li $v1, (1 << 28) /* IFS1<28> = DMA0IF = 0 */ + sw $v1, CLR($v0) + +irq_exit: + eret + nop + + + +/* Event routines. */ + +/* The vertical back porch. */ + +vbp_active: + /* Test for visible region. */ + + sltiu $v0, $s0, VISIBLE_START + bnez $v0, _vbp_active_ret + nop + + /* Start the visible region. */ + + la $s1, visible_active + +_vbp_active_ret: + jr $ra + nop + + + +/* The visible region. */ + +visible_active: + /* Test for front porch. */ + + sltiu $v0, $s0, VFP_START + bnez $v0, _visible_active_ret + nop + + /* Start the front porch region. */ + + la $s1, vfp_active + +_visible_active_ret: + jr $ra + nop + + + +/* Within the vertical front porch. */ + +vfp_active: + /* Test for vsync. */ + + sltiu $v0, $s0, VSYNC_START + bnez $v0, _vfp_active_ret + nop + + /* Start the vsync. */ + + la $s1, vsync_active + + /* Bring vsync low when the next line starts. */ + + la $v0, OC2CON + li $v1, 0b010 | (1 << 15) /* OC2CON<2:0> = OCM<2:0> = 010 (single compare, output driven low) */ + sw $v1, 0($v0) + +_vfp_active_ret: + jr $ra + nop + + + +/* The vsync period. */ + +vsync_active: + /* Test for front porch. */ + + sltiu $v0, $s0, VSYNC_END + bnez $v0, _vsync_active_ret + nop + + /* Start the back porch. */ + + move $s0, $zero + la $s1, vbp_active + + /* Bring vsync high when the next line starts. */ + + la $v0, OC2CON + li $v1, 0b001 | (1 << 15) /* OC2CON<2:0> = OCM<2:0> = 001 (single compare, output driven high) */ + sw $v1, 0($v0) + +_vsync_active_ret: + jr $ra + nop diff -r c2f73f8a609c -r e6fa4e9b4e4f vga.ld --- a/vga.ld Thu May 11 00:23:47 2017 +0200 +++ b/vga.ld Sun May 14 13:29:13 2017 +0200 @@ -9,8 +9,10 @@ MEMORY { kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000 - kseg0_program_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 0xBF0 - physical_program_mem (rx) : ORIGIN = 0x1FC00000, LENGTH = 0xBF0 + kseg0_boot_mem (rx) : ORIGIN = 0x9FC00000, LENGTH = 0xBF0 + kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x40000 + physical_boot_mem (rx) : ORIGIN = 0x1FC00000, LENGTH = 0xBF0 + physical_program_mem (rx) : ORIGIN = 0x1D000000, LENGTH = 0x40000 sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 configsfrs : ORIGIN = 0xBFC00BF0, LENGTH = 0x10 config3 : ORIGIN = 0xBFC00BF0, LENGTH = 0x4 @@ -25,12 +27,13 @@ SECTIONS { - .text : { *(.text*) } > kseg0_program_mem AT > physical_program_mem + .text : { *(.text*) } > kseg0_boot_mem AT > physical_boot_mem + .flash : { *(.flash*) } > kseg0_program_mem AT > physical_program_mem .bss : { *(.bss*) } > kseg1_data_mem .got : { _gp = ALIGN(16); *(.got*) - } > kseg0_program_mem AT > physical_program_mem + } > kseg0_boot_mem AT > physical_boot_mem .devcfg0 : { *(.devcfg0) } > config0 AT > physical_config0