# HG changeset patch # User jlarmour # Date 938116347 0 # Node ID e7ba79f6d3a84ef98e2b8063f0acbad6164a7136 # Parent 0b25345c9c69c1aaadb244187b8d8ea3ba491763 Merge from eCos master repository on 1999-09-23-20:10:25-BST diff --git a/packages/hal/arm/arch/current/ChangeLog b/packages/hal/arm/arch/current/ChangeLog --- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,26 @@ +1999-09-21 Gary Thomas + + * include/hal_arch.h: Remove FIXME about GDB register layout. + + * src/context.S (hal_thread_save_context): Change function prologue + to match APCS more closely (keeps GDB happier). + +1999-09-19 Gary Thomas + + * src/vectors.S (spurious_IRQ): Make sure interrupts are masked + when switching to IRQ mode. + + * src/hal_misc.c (exception_handler): GDB stubs only take over + memory exceptions. This allows proper handling when an application + has it's own IRQ/FIQ VSR. + +1999-09-13 Gary Thomas + + * src/vectors.S (handle_IRQ_or_FIQ): Allow spurious interrupts + to be ignored. Some platforms (CL7xxx) have non-debounced + interrupt sources which can vanish before the hardware can be + queried. + 1999-09-11 Jonathan Larmour * src/arm_stub.c (__computeSignal): Synchronise return value with diff --git a/packages/hal/arm/arch/current/include/arm_stub.h b/packages/hal/arm/arch/current/include/arm_stub.h --- a/packages/hal/arm/arch/current/include/arm_stub.h +++ b/packages/hal/arm/arch/current/include/arm_stub.h @@ -34,6 +34,9 @@ enum regnames { #define PS_C 0x20000000 #define PS_V 0x10000000 +#define PS_I CPSR_IRQ_DISABLE +#define PS_F CPSR_FIQ_DISABLE + typedef enum regnames regnames_t; /* Given a trap value TRAP, return the corresponding signal. */ diff --git a/packages/hal/arm/arch/current/include/hal_arch.h b/packages/hal/arm/arch/current/include/hal_arch.h --- a/packages/hal/arm/arch/current/include/hal_arch.h +++ b/packages/hal/arm/arch/current/include/hal_arch.h @@ -184,8 +184,6 @@ asm volatile (" .globl " #_label_ ";" //-------------------------------------------------------------------------- // Thread register state manipulation for GDB support. -// FIX ME!! What does GDB expect? - // GDB expects the registers in this structure: // r0..r10, fp, ip, sp, lr, pc - 4 bytes each // f0..f7 - 12 bytes each (N/A on ARM7) diff --git a/packages/hal/arm/arch/current/src/arm.ld b/packages/hal/arm/arch/current/src/arm.ld --- a/packages/hal/arm/arch/current/src/arm.ld +++ b/packages/hal/arm/arch/current/src/arm.ld @@ -61,7 +61,7 @@ GROUP(libtarget.a libgcc.a) .text _vma_ : _lma_ \ { stext = ABSOLUTE(.); \ PROVIDE (__stext = ABSOLUTE(.)); \ - *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) } \ + *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) }\ > _region_ \ etext = .; PROVIDE (__etext = .); diff --git a/packages/hal/arm/arch/current/src/arm_stub.c b/packages/hal/arm/arch/current/src/arm_stub.c --- a/packages/hal/arm/arch/current/src/arm_stub.c +++ b/packages/hal/arm/arch/current/src/arm_stub.c @@ -58,7 +58,6 @@ int __computeSignal (unsigned int trap_n /* Return the trap number corresponding to the last-taken trap. */ -volatile int jifl; int __get_trap_number (void) { // The vector is not not part of the GDB register set so get it diff --git a/packages/hal/arm/arch/current/src/context.S b/packages/hal/arm/arch/current/src/context.S --- a/packages/hal/arm/arch/current/src/context.S +++ b/packages/hal/arm/arch/current/src/context.S @@ -67,8 +67,8 @@ name: FUNC_START(hal_thread_switch_context) mov ip,sp // saved stack pointer - sub sp,sp,#ARMREG_SIZE // make space for saved registers - stmea sp,{r0-r10,fp,ip,lr,pc} + stmfd sp!,{fp,ip,lr,pc} // filler + stmfd sp!,{r0-r10,fp,ip,lr,pc} mrs r2,cpsr str r2,[sp,#armreg_cpsr] str sp,[r1] // return new stack pointer @@ -90,8 +90,8 @@ FUNC_START(hal_thread_load_context) msr cpsr,r0 ldr r0,[fp,#armreg_cpsr] msr spsr,r0 - ldmfd fp,{r0-r10,fp,sp,lr} // also restores saved PSR - movs pc,lr + ldmfd fp,{r0-r10,fp,sp,lr} + movs pc,lr // also restores saved PSR // ------------------------------------------------------------------------------ // HAL longjmp, setjmp implementations diff --git a/packages/hal/arm/arch/current/src/hal_misc.c b/packages/hal/arm/arch/current/src/hal_misc.c --- a/packages/hal/arm/arch/current/src/hal_misc.c +++ b/packages/hal/arm/arch/current/src/hal_misc.c @@ -70,6 +70,8 @@ extern void *__mem_fault_handler; processing is underway. The only vector that can't be handled this way is the illegal instruction vector which is used for breakpoint/single-step and must be maintained by the stubs at all times. + Note: the interrupt vectors are _not_ preempted as the stubs probably can't + handle them properly. */ #define ARM_VECTORS 8 @@ -82,20 +84,17 @@ static int exception_level; static void __take_over_debug_traps(void) { - int i; - for (i = 0; i < ARM_VECTORS; i++) { - hold_vectors[i] = hardware_vectors[i]; - hardware_vectors[i] = vectors[i]; - } + hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; + hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; + hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; + hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; } static void __restore_debug_traps(void) { - int i; - for (i = 0; i < ARM_VECTORS; i++) { - hardware_vectors[i] = hold_vectors[i]; - } + hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; + hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; } #endif @@ -114,15 +113,15 @@ exception_handler(HAL_SavedRegisters *re _hal_registers = regs; __handle_exception(); + if (--exception_level == 0) __restore_debug_traps(); + +#elif defined(CYGPKG_KERNEL_EXCEPTIONS) + // We should decode the vector and pass a more appropriate // value as the second argument. For now we simply pass a // pointer to the saved registers. We should also divert // breakpoint and other debug vectors into the debug stubs. - if (--exception_level == 0) __restore_debug_traps(); - -#elif defined(CYGPKG_KERNEL_EXCEPTIONS) - cyg_hal_deliver_exception( regs->vector, (CYG_ADDRWORD)regs ); #else diff --git a/packages/hal/arm/arch/current/src/vectors.S b/packages/hal/arm/arch/current/src/vectors.S --- a/packages/hal/arm/arch/current/src/vectors.S +++ b/packages/hal/arm/arch/current/src/vectors.S @@ -480,7 +480,12 @@ call_exception_handler: mrs r0,cpsr // move back to IRQ mode bic r0,r0,#CPSR_MODE_BITS - orr r0,r0,#CPSR_IRQ_MODE + orr r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE + msr cpsr,r0 + nop + nop + + orr r0,r0,#CPSR_IRQ_MODE msr cpsr,r0 mov sp,ip @@ -578,6 +583,10 @@ 10: #endif mov r0,v1 // vector # +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS + cmp r0,#0 // ignore spurious interrupts + beq spurious_IRQ +#endif // CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS ldr r1,.hal_interrupt_data ldr r1,[r1,v1,lsl #2] // handler data ldr r2,.hal_interrupt_handlers @@ -588,6 +597,10 @@ 10: mov lr,pc // invoke handler (call indirect mov pc,v3 // thru v3) +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS +spurious_IRQ: +#endif // CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS + #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK // If we are returning from the last nested interrupt, move back // to the thread stack. interrupt_end() must be called on the @@ -620,6 +633,11 @@ 10: ldr sp,[sp,#armreg_sp] mrs r0,cpsr // move back to IRQ mode + orr r0,r0,#CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE + msr cpsr,r0 + nop + nop + bic r0,r0,#CPSR_MODE_BITS orr r0,r0,#CPSR_IRQ_MODE msr cpsr,r0 diff --git a/packages/hal/arm/cl7211/current/ChangeLog b/packages/hal/arm/cl7211/current/ChangeLog --- a/packages/hal/arm/cl7211/current/ChangeLog +++ b/packages/hal/arm/cl7211/current/ChangeLog @@ -1,3 +1,29 @@ +1999-09-15 Gary Thomas + + * misc/nand_test.c (nand_exercise): Check "read ID" function. + + * misc/lcd_panel_support.c (lcd_panel_server): Reorg sampling + loop to use a weighted average (try and avoid bad results). + + * misc/kbd_test.c (kbd_exercise): Use new kbd_getc() function. + + * misc/kbd_support.c (kbd_getc): New function. + + * misc/lcd_support.c: Add simple printf() code. + +1999-09-13 Gary Thomas + + * include/pkgconf/mlt_arm_eb7211_ram.ldi: + * include/pkgconf/mlt_arm_eb7211_ram.mlt: Fix DRAM limits. + +1999-09-12 Gary Thomas + + * misc/kbd_support.c: New file. Also change to more or less + ignore interrupts since they don't work for many keys! + + * misc/kbd_test.c: Move keyboard support routines to separate + file. + 1999-09-10 Gary Thomas * include/hal_platform_setup.h: Fix spelling error. diff --git a/packages/hal/arm/cl7211/current/images/gdb_module.bin b/packages/hal/arm/cl7211/current/images/gdb_module.bin index 54384e59563b3a0492f0e638a3e00cb1fcfe06c4..2c7a2a184b51637e191c514dccbddc5fba971895 GIT binary patch literal 16068 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 Q!}qee$C&-M keycode +static cyg_uint32 kbd_map[8][16] = { + // Column #0 + {KBD_Escape, KBD_1, KBD_Tab, KBD_CapsLock, + KBD_BackSlash, KBD_Space, KBD_LeftArrow, KBD_UpArrow, + KBD_DownArrow, KBD_RightArrow, KBD_LeftShift, KBD_Ctrl, + KBD_Function, KBD_LeftAlt, KBD_RightAlt, KBD_RightShift }, + // Column #1 + {KBD_F5, KBD_6, KBD_T, KBD_G, + KBD_B, KBD_Slash, KBD_SemiColon, KBD_P, + KBD_Hyphen, KBD_F10, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #2 + {KBD_F4, KBD_5, KBD_R, KBD_F, + KBD_V, KBD_Del, KBD_Quote, KBD_LeftBrkt, + KBD_Equals, KBD_NumLock, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #3 + {KBD_F3, KBD_4, KBD_E, KBD_D, + KBD_C, KBD_Ins, KBD_Empty, KBD_RightBrkt, + KBD_BackSpace, KBD_SysReq, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #4 + {KBD_F2, KBD_3, KBD_W, KBD_S, + KBD_X, KBD_Empty, KBD_Enter, KBD_Empty, + KBD_Empty, KBD_ScrlLock, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #5 + {KBD_F1, KBD_2, KBD_Q, KBD_A, + KBD_Z, KBD_End, KBD_PageDown, KBD_PageUp, + KBD_Home, KBD_Break, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #6 + {KBD_F6, KBD_7, KBD_Y, KBD_H, + KBD_N, KBD_Period, KBD_L, KBD_O, + KBD_0, KBD_F9, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, + // Column #7 + {KBD_F7, KBD_8, KBD_U, KBD_J, + KBD_M, KBD_Comma, KBD_K, KBD_I, + KBD_9, KBD_F8, KBD_Empty, KBD_Empty, + KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, +}; + +static cyg_uint8 kbd_chars[96] = { + /* 0x00 - 0x0F */ + 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x10 - 0x1F */ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0x08, 0x00, 0x00, 0x00, + /* 0x20 - 0x2F */ + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\', 0x00, 0x00, + /* 0x30 - 0x3F */ + 0x00, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 0x0D, 0x00, 0x00, 0x00, + /* 0x40 - 0x4F */ + 0x00, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x50 - 0x5F */ + 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static cyg_uint8 kbd_shifted_chars[96] = { + /* 0x00 - 0x0F */ + '\b', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x10 - 0x1F */ + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0x08, 0x00, 0x00, 0x00, + /* 0x20 - 0x2F */ + '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '|', 0x00, 0x00, + /* 0x30 - 0x3F */ + 0x00, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', 0x0D, 0x00, 0x00, 0x00, + /* 0x40 - 0x4F */ + 0x00, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x50 - 0x5F */ + 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +// This ISR is called when the keyboard interrupt occurs +static int +keyboard_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) +{ + cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_KBDINT); + return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR +} + +// This DSR handles the keyboard [logical] processing +static void +keyboard_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + // Tell the keyboard processing thread to give it a shot + cyg_semaphore_post(&kbd_sem); +} + +static void +kbd_server(cyg_addrword_t p) +{ + int col, bit, key, event, timeout; + diag_printf("KBD server here\n"); + while (TRUE) { + cyg_semaphore_wait(&kbd_sem); + // As long as keys are pressed, scan and update + timeout = 0; + while (TRUE) { + // Wait for 20ms - time to debounce keyboard + cyg_thread_delay(2); + // Scan keyboard + kbd_scan(); + // Reset state + for (key = 0; key < sizeof(kbd_new_state); key++) { + kbd_new_state[key] = 0; + } + // Check state of all keys and send events for those that change + for (col = 0; col < 8; col++) { + for (bit = 0; bit < 8; bit++) { + if (col_state[col] & (1< keycode -static cyg_uint32 kbd_map[8][16] = { - // Column #0 - {KBD_Escape, KBD_1, KBD_Tab, KBD_CapsLock, - KBD_BackSlash, KBD_Space, KBD_LeftArrow, KBD_UpArrow, - KBD_DownArrow, KBD_RightArrow, KBD_LeftShift, KBD_Ctrl, - KBD_Function, KBD_LeftAlt, KBD_RightAlt, KBD_RightShift }, - // Column #1 - {KBD_F5, KBD_6, KBD_T, KBD_G, - KBD_B, KBD_Slash, KBD_SemiColon, KBD_P, - KBD_Hyphen, KBD_F10, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #2 - {KBD_F4, KBD_5, KBD_R, KBD_F, - KBD_V, KBD_Del, KBD_Quote, KBD_LeftBrkt, - KBD_Equals, KBD_NumLock, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #3 - {KBD_F3, KBD_4, KBD_E, KBD_D, - KBD_C, KBD_Ins, KBD_Empty, KBD_RightBrkt, - KBD_BackSpace, KBD_SysReq, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #4 - {KBD_F2, KBD_3, KBD_W, KBD_S, - KBD_X, KBD_Empty, KBD_Enter, KBD_Empty, - KBD_Empty, KBD_ScrlLock, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #5 - {KBD_F1, KBD_2, KBD_Q, KBD_A, - KBD_Z, KBD_End, KBD_PageDown, KBD_PageUp, - KBD_Home, KBD_Break, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #6 - {KBD_F6, KBD_7, KBD_Y, KBD_H, - KBD_N, KBD_Period, KBD_L, KBD_O, - KBD_Empty, KBD_F9, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, - // Column #7 - {KBD_F7, KBD_8, KBD_U, KBD_J, - KBD_M, KBD_Comma, KBD_K, KBD_I, - KBD_Empty, KBD_F8, KBD_Empty, KBD_Empty, - KBD_Empty, KBD_Empty, KBD_Empty, KBD_Empty }, -}; - -static cyg_uint8 kbd_chars[96] = { - /* 0x00 - 0x0F */ - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0x10 - 0x1F */ - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0x08, 0x00, 0x00, 0x00, - /* 0x20 - 0x2F */ - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\', 0x00, 0x00, - /* 0x30 - 0x3F */ - 0x00, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 0x0D, 0x00, 0x00, 0x00, - /* 0x40 - 0x4F */ - 0x00, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0x50 - 0x5F */ - 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static cyg_uint8 kbd_shifted_chars[96] = { - /* 0x00 - 0x0F */ - '\b', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0x10 - 0x1F */ - '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0x08, 0x00, 0x00, 0x00, - /* 0x20 - 0x2F */ - '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '|', 0x00, 0x00, - /* 0x30 - 0x3F */ - 0x00, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', 0x0D, 0x00, 0x00, 0x00, - /* 0x40 - 0x4F */ - 0x00, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0x50 - 0x5F */ - 0x00, 0x00, 0x00, 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -// This ISR is called when the keyboard interrupt occurs -int -keyboard_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) -{ - cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_KBDINT); - return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR -} - -// This DSR handles the keyboard [logical] processing -void -keyboard_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - // Tell the keyboard processing thread to give it a shot - cyg_semaphore_post(&kbd_sem); -} - -static void -kbd_server(cyg_addrword_t p) -{ - int col, bit, key, event, timeout; - diag_printf("KBD server here\n"); - // This semaphore is set when there is a keypress - cyg_semaphore_init(&kbd_sem, 0); - while (TRUE) { - cyg_semaphore_wait(&kbd_sem); - // As long as keys are pressed, scan and update - timeout = 0; - while (TRUE) { - // Wait for 20ms - time to debounce keyboard - cyg_thread_delay(2); - // Scan keyboard - kbd_scan(); - // Reset state - for (key = 0; key < sizeof(kbd_new_state); key++) { - kbd_new_state[key] = 0; - } - // Check state of all keys and send events for those that change - for (col = 0; col < 8; col++) { - for (bit = 0; bit < 8; bit++) { - if (col_state[col] & (1<= width) X = width-1; + curX = X; + if (Y < 0) Y = 0; + if (Y >= height) Y = height-1; + curY = Y; + lcd_drawc(CURSOR_ON, curX, curY); } // Render a character at position (X,Y) with current background/foreground @@ -291,9 +309,11 @@ lcd_drawc(cyg_int8 c, int x, int y) } } -static void +// Draw one character at the current position +void lcd_putc(cyg_int8 c) { + lcd_drawc(CURSOR_OFF, curX, curY); switch (c) { case '\r': curX = 0; @@ -308,6 +328,7 @@ lcd_putc(cyg_int8 c) if (curY < 0) curY = 0; curX = width-1; } + break; default: lcd_drawc(c, curX, curY); curX++; @@ -316,5 +337,163 @@ lcd_putc(cyg_int8 c) curX = 0; } } + lcd_drawc(CURSOR_ON, curX, curY); +} + +// Basic LCD 'printf()' support + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#include + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +static int +_cvt(unsigned long val, char *buf, long radix, char *digits) +{ + char temp[80]; + char *cp = temp; + int length = 0; + if (val == 0) { + /* Special case */ + *cp++ = '0'; + } else { + while (val) { + *cp++ = digits[val % radix]; + val /= radix; + } + } + while (cp != temp) { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); } +int +lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap) +{ + char c, sign, *cp; + int left_prec, right_prec, zero_fill, length, pad, pad_on_right; + char buf[32]; + long val; + while ((c = *fmt0++)) { + cp = buf; + length = 0; + if (c == '%') { + c = *fmt0++; + left_prec = right_prec = pad_on_right = 0; + if (c == '-') { + c = *fmt0++; + pad_on_right++; + } + if (c == '0') { + zero_fill = TRUE; + c = *fmt0++; + } else { + zero_fill = FALSE; + } + while (is_digit(c)) { + left_prec = (left_prec * 10) + (c - '0'); + c = *fmt0++; + } + if (c == '.') { + c = *fmt0++; + zero_fill++; + while (is_digit(c)) { + right_prec = (right_prec * 10) + (c - '0'); + c = *fmt0++; + } + } else { + right_prec = left_prec; + } + sign = '\0'; + switch (c) { + case 'd': + case 'x': + case 'X': + val = va_arg(ap, long); + switch (c) { + case 'd': + if (val < 0) { + sign = '-'; + val = -val; + } + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; + } + break; + case 's': + cp = va_arg(ap, char *); + length = strlen(cp); + break; + case 'c': + c = va_arg(ap, long /*char*/); + (*putc)(c); + continue; + default: + (*putc)('?'); + } + pad = left_prec - length; + if (sign != '\0') { + pad--; + } + if (zero_fill) { + c = '0'; + if (sign != '\0') { + (*putc)(sign); + sign = '\0'; + } + } else { + c = ' '; + } + if (!pad_on_right) { + while (pad-- > 0) { + (*putc)(c); + } + } + if (sign != '\0') { + (*putc)(sign); + } + while (length-- > 0) { + (*putc)(c = *cp++); + if (c == '\n') { + (*putc)('\r'); + } + } + if (pad_on_right) { + while (pad-- > 0) { + (*putc)(' '); + } + } + } else { + (*putc)(c); + if (c == '\n') { + (*putc)('\r'); + } + } + } +} + +int +lcd_printf(char const *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = lcd_vprintf(lcd_putc, fmt, ap); + va_end(ap); + return (ret); +} + diff --git a/packages/hal/arm/cl7211/current/misc/panel_test.c b/packages/hal/arm/cl7211/current/misc/panel_test.c --- a/packages/hal/arm/cl7211/current/misc/panel_test.c +++ b/packages/hal/arm/cl7211/current/misc/panel_test.c @@ -31,7 +31,7 @@ // // Author(s): gthomas // Contributors: gthomas -// Date: 1999-05-15 +// Date: 1999-09-06 // Description: Tool used to test LCD touch panel //####DESCRIPTIONEND#### @@ -56,19 +56,9 @@ static char stack[STACK_SIZE]; static cyg_thread thread_data; static cyg_handle_t thread_handle; -static cyg_interrupt panel_interrupt; -static cyg_handle_t panel_interrupt_handle; #include "lcd_support.c" - -#define SYNCIO_TXFRMEN (1<<14) -#define SYNCIO_FRAMELEN(n) (n<<8) -#define ADC_START (1<<7) -#define ADC_CHAN(n) (n<<4) -#define ADC_UNIPOLAR (1<<3) -#define ADC_SINGLE (1<<2) -#define ADC_EXT_CLOCK (3<<0) -#define TOUCH_CTL KBD_PORT +#include "lcd_panel_support.c" // FUNCTIONS @@ -78,78 +68,20 @@ cyg_test_exit(void) while (TRUE) ; } -static cyg_uint32 -adc_sample(int chan) -{ - cyg_uint32 val; - *(volatile cyg_uint32 *)SYNCIO = SYNCIO_TXFRMEN | SYNCIO_FRAMELEN(24) | - ADC_START | ADC_CHAN(chan) | ADC_UNIPOLAR | ADC_SINGLE | ADC_EXT_CLOCK; - while (*(volatile cyg_uint32 *)SYSFLG1 & SYSFLG1_SSIBUSY) ; - val = *(volatile cyg_uint32 *)SYNCIO; - return val & 0xFFFF; -} - -static void -panel_delay(void) -{ - volatile int i; - for (i = 0; i < 50; i++) ; -} - -// This ISR is called when the touch panel interrupt occurs -int -cyg_hal_panel_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) -{ - int iX, iY; - cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EINT2); - diag_printf("Touched!\n"); - *(volatile cyg_uint8 *)TOUCH_CTL = 0x50; // Drive TSPY, ground TSMY, and disconnect TSPX and TSMX - panel_delay(); - iY = adc_sample(2); - *(volatile cyg_uint8 *)TOUCH_CTL = 0xA0; // Drive TSPX, ground TSMX, and disconnect TSPY and TSMY - panel_delay(); - iX = adc_sample(7); - diag_printf("X = %d, Y = %d, ISR1: %x\n", iX, iY, *(volatile cyg_uint32 *)INTSR1); - *(volatile cyg_uint8 *)TOUCH_CTL = 0x00; // Disable drives - while (*(volatile cyg_uint32 *)INTSR1 & INTSR1_EINT2) ; - *(volatile cyg_uint8 *)TOUCH_CTL = 0x70; // Idle state (so interrupt works) -// cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2); - return 0; // No need to run DSR -} - static void panel_exercise(cyg_addrword_t p) { - int i, j; + int i; + cyg_uint32 val; + diag_printf("LCD touch panel test here!\n"); - *(volatile cyg_uint8 *)PEDDR = 0x0F; // Register E data direction - *(volatile cyg_uint8 *)PEDR |= 0x04; // Enable touch panel - - diag_printf("PEDR = %x\n", *(volatile cyg_uint8 *)PEDR); - - *(volatile cyg_uint8 *)TOUCH_CTL = 0x70; // Idle state (so interrupt works) - - lcd_on(4); - lcd_clear(); - - *(volatile cyg_uint32 *)SYSCON1 |= SYSCON1_ADC_CLOCK_128kHZ; - - cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT2, - 99, // Priority - what goes here? - 0, // Data item passed to interrupt handler - cyg_hal_panel_isr, - 0, - &panel_interrupt_handle, - &panel_interrupt); - cyg_drv_interrupt_attach(panel_interrupt_handle); - cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT2); - cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2); + lcd_panel_init(); for (i = 0; i < 50; i++) { diag_printf("Please touch screen now:\n"); - cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2); - cyg_thread_delay(5*100); + val = (cyg_uint32)cyg_mbox_get(lcd_panel_events_mbox_handle); + diag_printf("val = %x, X = %d, Y = %d\n", val, (val>>16), val & 0xFFFF); } diag_printf("All done!\n"); diff --git a/packages/hal/arm/cl7211/current/src/cl7211_misc.c b/packages/hal/arm/cl7211/current/src/cl7211_misc.c --- a/packages/hal/arm/cl7211/current/src/cl7211_misc.c +++ b/packages/hal/arm/cl7211/current/src/cl7211_misc.c @@ -279,6 +279,8 @@ void hal_hardware_init(void) // reading the hardware a lot, since the interrupt status is split across // three separate registers. +int hal_spurious_ints; + int hal_IRQ_handler(void) { struct regmap *map = hal_interrupt_status_regmap; @@ -291,6 +293,7 @@ int hal_IRQ_handler(void) } map++; // Next interrupt status register } + hal_spurious_ints++; return CYGNUM_HAL_INTERRUPT_unused; // This shouldn't happen! } diff --git a/packages/hal/arm/cl7211/current/src/hal_diag.c b/packages/hal/arm/cl7211/current/src/hal_diag.c --- a/packages/hal/arm/cl7211/current/src/hal_diag.c +++ b/packages/hal/arm/cl7211/current/src/hal_diag.c @@ -86,6 +86,7 @@ #endif #endif + /*---------------------------------------------------------------------------*/ // CL7211 Serial Port (UARTx) for Debug diff --git a/packages/hal/arm/cl7211/current/src/plf_stub.c b/packages/hal/arm/cl7211/current/src/plf_stub.c --- a/packages/hal/arm/cl7211/current/src/plf_stub.c +++ b/packages/hal/arm/cl7211/current/src/plf_stub.c @@ -73,6 +73,7 @@ static cyg_interrupt gdb_interrupt; static cyg_handle_t gdb_interrupt_handle; #endif + //----------------------------------------------------------------------------- #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT diff --git a/packages/hal/arm/cl7211/current/support/Makefile b/packages/hal/arm/cl7211/current/support/Makefile --- a/packages/hal/arm/cl7211/current/support/Makefile +++ b/packages/hal/arm/cl7211/current/support/Makefile @@ -3,8 +3,12 @@ # DL_FILES = dl_7211.o io.o +DOWNLOAD_FILES = download_file.o io.o -all: dl_7211 +all: dl_7211 download dl_7211: $(DL_FILES) - $(CC) -o $@ $(DL_FILES) \ No newline at end of file + $(CC) -o $@ $(DL_FILES) + +download: $(DOWNLOAD_FILES) + $(CC) -o $@ $(DOWNLOAD_FILES) diff --git a/packages/hal/arm/cl7211/current/support/download_file.c b/packages/hal/arm/cl7211/current/support/download_file.c new file mode 100644 --- /dev/null +++ b/packages/hal/arm/cl7211/current/support/download_file.c @@ -0,0 +1,260 @@ +//**************************************************************************** +// +// download_file.c - Send a raw data file to the EB72xx board. +// +// Adapted from the Cirrus Logic 'DOWNLOAD.C' program +// +// Copyright (c) 1999 Cirrus Logic, Inc. +// +// Adapted for Linux by Cygnus Solutions, Inc. +// +//**************************************************************************** +#include +#include "bootcode.h" + +#define DEFAULT_PORT "/dev/ttyS0" +extern char ReceiveChar(long); +extern void SendChar(long, char); +extern void SetBaud(long, long); +extern int CharRead(long port); +extern void WaitForOutputReady(long port); +extern long OpenPort(char *); + +//**************************************************************************** +// +// WaitFor waits until a specific character is read from the comm port. +// +//**************************************************************************** +void +WaitFor(long lPort, char cWaitChar) +{ + char cChar; + + // + // Wait until we read a specific character from the comm port. + // + while(1) + { + // + // Read a character. + // + cChar = ReceiveChar(lPort); + + // + // Stop waiting if we received the character. + // + if(cChar == cWaitChar) + { + break; + } + } +} + +//**************************************************************************** +// +// This program waits for the '<' character from the boot ROM, sends the boot +// code, waits for the '>' from the boot ROM, waits for the '?' from the boot +// code, changes the serial port rate (preferably to 115200), downloads the +// user data file, and then prints out progress status as the boot code writes +// the user data file to the flash. +// +//**************************************************************************** +void +main(int argc, char *argv[]) +{ + long lPort; + long lRate = 38400; + long lFileSize, lIdx; + char cChar, cFirstChar, *pcFile, cRateChar; + FILE *pFile; + + // + // Make sure that a filename was specified. + // + if(argc < 2) + { + fprintf(stderr, "Usage: download { {}}\n"); + return; + } + + // + // If a baud rate was specified, then read it and make sure it is valid. + // + if(argc > 2) + { + lRate = atoi(argv[2]); + if((lRate != 9600) && (lRate != 19200) && (lRate != 28800) && + (lRate != 38400) && (lRate != 57600) && (lRate != 115200)) + { + fprintf(stderr, "Invalid baud rate.\n"); + return; + } + } + + // + // If a comm port was specified, then read it and make sure it is valid. + // + if(argc > 3) + { + lPort = OpenPort(argv[3]); + } else + { + lPort = OpenPort(DEFAULT_PORT); + } + if (lPort < 0) + { + fprintf(stderr, "Can't open port\n"); + return; + } + + // + // Open the file to be downloaded. + // + pFile = fopen(argv[1], "rb"); + if(!pFile) + { + fprintf(stderr, "Could not open file '%s'.\n", argv[1]); + return; + } + + // + // Get the size of the file. + // + fseek(pFile, 0, SEEK_END); + lFileSize = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + + // + // Allocate memory to hold the file contents. + // + pcFile = (char *)malloc(lFileSize); + if(!pcFile) + { + fprintf(stderr, "Failed to allocate memory for the file.\n"); + return; + } + + // + // Read the contents of the file into memory. + // + if(fread(pcFile, 1, lFileSize, pFile) != lFileSize) + { + fprintf(stderr, "Failed to read file '%s'.\n", argv[1]); + return; + } + + // + // Close the file. + // + fclose(pFile); + + // + // Open the port to the desired baud rate. + // + SetBaud(lPort, lRate); + + // + // Empty out the input queue. + // + while(CharReady(lPort)) + { + cChar = ReceiveChar(lPort); + } + + // + // Tell the user to reset the board. + // + fprintf(stderr, "Waiting for the board to wakeup..."); + + // + // Send a '-' character until we receive back a '?' character. + // + while(1) + { + // + // Send a '-' character. + // + SendChar(lPort, '-'); + + // + // Wait a little bit. + // + for(lIdx = 0; lIdx < 1024 * 1024; lIdx++) + { + } + + // + // See if there is a character waiting to be read. + // + if(CharReady(lPort)) + { + // + // Read the character. + // + cChar = ReceiveChar(lPort); + + // + // Quit waiting if this is a '?'. + // + if(cChar == '?') + { + break; + } + } + } + + // + // Empty out the input queue. + // + while(CharReady(lPort)) + { + cChar = ReceiveChar(lPort); + } + + // + // Send the download file "command" + // + SendChar(lPort, 'D'); + + // + // Send the length of the data file. + // + SendChar(lPort, (char)(lFileSize & 0xFF)); + SendChar(lPort, (char)((lFileSize >> 8) & 0xFF)); + SendChar(lPort, (char)((lFileSize >> 16) & 0xFF)); + SendChar(lPort, (char)((lFileSize >> 24) & 0xFF)); + + // + // Tell the user that we are downloading the file data. + // + fprintf(stderr, "\nDownloading file data...( 0%%)"); + + // + // Send the actual data in the file. + // + for(lIdx = 0; lIdx < lFileSize; lIdx++) + { + // + // Send this byte. + // + SendChar(lPort, pcFile[lIdx]); + + // + // Periodically print out our progress. + // + if((lIdx & 127) == 127) + { + fprintf(stderr, "\b\b\b\b\b%3d%%)", ((lIdx + 1) * 100) / lFileSize); + // + // Read a character from the boot code. + // + cChar = ReceiveChar(lPort); + } + } + + // + // Tell the user we are done. + // + fprintf(stderr, "\nSuccessfully downloaded '%s'.\n", argv[1]); +} + diff --git a/packages/hal/common/current/ChangeLog b/packages/hal/common/current/ChangeLog --- a/packages/hal/common/current/ChangeLog +++ b/packages/hal/common/current/ChangeLog @@ -1,3 +1,15 @@ +1999-09-21 Gary Thomas + + * src/thread-packets.c: Fix some typos in comments. + +1999-09-13 Gary Thomas + + * include/pkgconf/hal.h: Add new config option to allow spurious + interrupts to be ignored by the HAL. + + * src/generic-stub.c (__process_packet): Build in version string + (date/time) for stubs in ROM to be returned via 'd' packet. + 1999-09-09 Jonathan Larmour * include/pkgconf/hal.h (CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS): Rename diff --git a/packages/hal/common/current/include/pkgconf/hal.h b/packages/hal/common/current/include/pkgconf/hal.h --- a/packages/hal/common/current/include/pkgconf/hal.h +++ b/packages/hal/common/current/include/pkgconf/hal.h @@ -205,6 +205,18 @@ of RAM needed for interrupt decoding tables and code." } + cdl_option CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS { + display "Ignore spurious [fleeting] interrupts" + parent CYGPKG_HAL_COMMON_INTERRUPTS + description " + On some hardware, interrupt sources may not be de-bounced or + de-glitched. Rather than try to handle these interrupts (no + handling may be possible), this option allows the HAL to simply + ignore them. In most cases, if the interrupt is real it will + reoccur in a detectable form." + } + + }}CFG_DATA */ @@ -214,6 +226,7 @@ #undef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING #define CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT #undef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN +#undef CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS /* {{CFG_DATA diff --git a/packages/hal/common/current/src/generic-stub.c b/packages/hal/common/current/src/generic-stub.c --- a/packages/hal/common/current/src/generic-stub.c +++ b/packages/hal/common/current/src/generic-stub.c @@ -838,6 +838,11 @@ int case 'd': /* toggle debug flag */ +#ifdef __ECOS__ +#if !defined(CYG_HAL_STARTUP_RAM) // Only for ROM based stubs + strcpy(remcomOutBuffer, "eCos GDB stubs - built " __DATE__ " / " __TIME__); +#endif +#endif // __ECOS__ break; case 'q': diff --git a/packages/hal/common/current/src/hal_stub.c b/packages/hal/common/current/src/hal_stub.c --- a/packages/hal/common/current/src/hal_stub.c +++ b/packages/hal/common/current/src/hal_stub.c @@ -117,6 +117,7 @@ void #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT + #if (HAL_BREAKINST_SIZE == 1) typedef cyg_uint8 t_inst; #elif (HAL_BREAKINST_SIZE == 2) @@ -162,6 +163,7 @@ cyg_hal_gdb_remove_break (target_registe return 0; } + #endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT // Use this function to disable serial interrupts whenever reply diff --git a/packages/hal/common/current/src/thread-packets.c b/packages/hal/common/current/src/thread-packets.c --- a/packages/hal/common/current/src/thread-packets.c +++ b/packages/hal/common/current/src/thread-packets.c @@ -160,7 +160,7 @@ static char * unpack_int(char * buf, int return buf + 8 ; } -/* We are NOT depending upun extensive libraries */ +/* We are NOT depending upon extensive libraries */ static int ishex(char ch,int *val) { if ((ch >= 'a') && (ch <= 'f')) @@ -211,7 +211,7 @@ static char * pack_varlen_hex( n[i] = value & 0x0f ; value = value >> 4 ; } - i = 0 ; /* we had descrmented it to -1 */ + i = 0 ; /* we had decrmented it to -1 */ while (n[i] == 0 ) i++ ; /* drop leading zeroes */ while (i++ < 8) *pkt++ = hexchars[n[i]] ; /* pack the number */ } @@ -336,8 +336,8 @@ static char * pack_threadid(char * pkt, return pkt ; } /* stub_pack_threadid */ -/* UNFORTUNATLY, not all ow the extended debugging system has yet been - converted to 64 but thread referenecces and process identifiers. +/* UNFORTUNATELY, not all of the extended debugging system has yet been + converted to 64 but thread references and process identifiers. These routines do the conversion. An array of bytes is the correct treatment of an opaque identifier. ints have endian issues. diff --git a/packages/hal/mips/arch/current/ChangeLog b/packages/hal/mips/arch/current/ChangeLog --- a/packages/hal/mips/arch/current/ChangeLog +++ b/packages/hal/mips/arch/current/ChangeLog @@ -1,3 +1,32 @@ +1999-09-17 Jonathan Larmour + + * src/vectors.S (__default_exception_vsr): + Rename exception_handler()->cyg_hal_exception_handler() + After all, we will just do a jump rather than a jal into + cyg_hal_exception_handler() + (restore_state): Make the change below (by Hugo) be conditional + on CYG_HAL_USE_ROM_MONITOR_CYGMON. + Add explanatory comment about the additions for Cygmon + + * src/hal_misc.c (hal_default_isr): Use new format HAL_DIAG_IRQ_CHECK() + and check return code is negative; if so, return + (cyg_hal_exception_handler): Rename from exception_handler() + Now return cyg_uint32, but default to returning 0 always + +1999-09-16 Hugo Tyson + + This set of changes with matching ones in jmr3904 comes from Mark + Salter's work to make jmr3904 CygMon talk Ethernet. + + * src/vectors.S (restore_state): Call CygMon for exceptions or + unhandled interrupts if CYG_HAL_USE_ROM_MONITOR. This is why the + return value from the ISR is preserved. Don't fully understand + this. + + * src/hal_misc.c (hal_default_isr): Call into hal_diag via + HAL_DIAG_IRQ_CHECK if it's defined and CYG_HAL_USE_ROM_MONITOR. + This lets CygMon check for network interrupts &c. + 1999-09-09 Nick Garnett * include/arch.inc: diff --git a/packages/hal/mips/arch/current/src/hal_misc.c b/packages/hal/mips/arch/current/src/hal_misc.c --- a/packages/hal/mips/arch/current/src/hal_misc.c +++ b/packages/hal/mips/arch/current/src/hal_misc.c @@ -72,7 +72,7 @@ externC void *__mem_fault_handler; externC cyg_uint8 cyg_hal_mips_process_fpe( HAL_SavedRegisters *regs ); -externC void exception_handler(HAL_SavedRegisters *regs) +externC cyg_uint32 cyg_hal_exception_handler(HAL_SavedRegisters *regs) { #ifdef CYGHWR_HAL_MIPS_FPU // We may be required to emulate certain unimplemented Floating Point @@ -84,7 +84,7 @@ externC void exception_handler(HAL_Saved // the exception successfully. If so, we just return if ( cyg_hal_mips_process_fpe(regs) ) - return; + return 0; } #endif @@ -94,7 +94,7 @@ externC void exception_handler(HAL_Saved // and if so jump to the saved address if (__mem_fault_handler) { regs->pc = (CYG_ADDRWORD)__mem_fault_handler; - return; // Caught an exception inside stubs + return 0; // Caught an exception inside stubs } // Set the pointer to the registers of the current exception @@ -117,7 +117,7 @@ externC void exception_handler(HAL_Saved CYG_FAIL("Exception!!!"); #endif - return; + return 0; } /*------------------------------------------------------------------------*/ @@ -137,6 +137,17 @@ externC cyg_uint32 hal_default_isr(CYG_A if( result != 0 ) return result; } +#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) +#if defined(HAL_DIAG_IRQ_CHECK) + { + cyg_uint32 ret; + /* let ROM monitor handle unexpected interrupts */ + HAL_DIAG_IRQ_CHECK(vector, ret); + if (ret<=0) + return ret; + } +#endif // def HAL_DIAG_IRQ_CHECK +#endif // def CYG_HAL_USE_ROM_MONITOR #endif CYG_TRACE1(true, "Interrupt: %d", vector); diff --git a/packages/hal/mips/arch/current/src/vectors.S b/packages/hal/mips/arch/current/src/vectors.S --- a/packages/hal/mips/arch/current/src/vectors.S +++ b/packages/hal/mips/arch/current/src/vectors.S @@ -377,8 +377,8 @@ FUNC_START(__default_exception_vsr) hal_cpu_except_enable # reenable exceptions - .extern exception_handler - j exception_handler # call C code + .extern cyg_hal_exception_handler + j cyg_hal_exception_handler # call C code move a0,s0 # arg0 = register dump (delay slot) # When the exception handler returns, it will @@ -562,7 +562,7 @@ 8: lw sp,mips_stack_frame_size(sp) # sp = *sp subu sp,sp,mips_stack_frame_size # make a null frame -#endif +#endif #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT @@ -579,7 +579,7 @@ 8: # the register dump, the vector offset and the interrupt number # respectively. - move a0,v0 # put ISR result in arg0 + move s2,v0 la a1,hal_interrupt_objects # interrupt object table add a1,a1,s1 # address of object ptr @@ -589,11 +589,13 @@ 8: .extern interrupt_end jal interrupt_end # call into C to finish off - nop # (delay slot) - + move a0,v0 # put ISR result in arg0 + + move v0,s2 # return value from isr #endif -restore_state: +restore_state: + move k0,v0 # All done, restore CPU state and continue @@ -648,7 +650,36 @@ restore_state: lw $30,(mipsreg_regs+30*4)(sp) # == FP lw $31,(mipsreg_regs+31*4)(sp) # == RA .set at - + + +#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) + + # If we have a Cygmon that wants to listen to network interrupts, then + # the return code from the earlier call to hal_default_isr() will + # have been negative to indicate this. So we jump into Cygmon here + # because Cygmon requires the processor state to be the same as when + # the interrupt was taken, but with k0 as the exception number. + + bgez k0,1f + nop + # Check for new cygmon + sw k0,(mipsreg_regs+26*4)(sp) # save k0 + la k1,0x80000100 + 41*4 # New cygmon "magic" id + lw k1,0(k1) + lui k0,0x55aa + ori k0,0x4321 + bne k0,k1,1f + + # Need to let cygmon handle this + la k1,0x80000100 + 39*4 # stub entry vector + lw k0,(mipsreg_regs+26*4)(sp) # restore k0 + lw k1,0(k1) + lw sp,(mipsreg_regs+29*4)(sp) # restore SP + sll k0,1 # clear bit 31. + jr k1 + srl k0,1 + 1: +#endif lw k0,mipsreg_pc(sp) # K0 = return PC lw k1,mipsreg_sr(sp) # K1 = saved SR lw sp,(mipsreg_regs+29*4)(sp) # load SP diff --git a/packages/hal/mips/tx39/current/ChangeLog b/packages/hal/mips/tx39/current/ChangeLog --- a/packages/hal/mips/tx39/current/ChangeLog +++ b/packages/hal/mips/tx39/current/ChangeLog @@ -1,3 +1,31 @@ +1999-09-17 Jonathan Larmour + + * src/hal_diag.c: Only avoid SERIAL0 if CYG_HAL_USE_ROM_MONITOR_CYGMON + since we default to assuming Cygmon + + * include/variant.inc (hal_memc_init): Don't make conditional on + ROM startup - makes sense anyway so that users can change amount + of memory in system + (hal_memc_init_dram): Likewise + + * include/var_arch.h (HAL_DIAG_IRQ_CHECK): Give extra return parameter + rather than relying on this being an expression which evaluates + +1999-09-16 Hugo Tyson + + This set of changes with matching ones in arch comes from Mark + Salter's work to make jmr3904 CygMon talk Ethernet. + + * include/variant.inc: Do not re-initialize and disable all + interrupts if RAM start, this stops networked CygMon working. + Likewise don't re-init memory. + + * src/hal_diag.c: Add alternate hal_diag...() routines that talk + via CygMon so that ethernet debugging works. + + * include/var_arch.h: If CYG_HAL_USE_ROM_MONITOR, export macro for + polling unknown interrupts in CygMon, HAL_DIAG_IRQ_CHECK. + 1999-08-25 Nick Garnett * include/variant.inc: Added clock-speed dependent values for the diff --git a/packages/hal/mips/tx39/current/include/var_arch.h b/packages/hal/mips/tx39/current/include/var_arch.h --- a/packages/hal/mips/tx39/current/include/var_arch.h +++ b/packages/hal/mips/tx39/current/include/var_arch.h @@ -47,6 +47,16 @@ #include #include +#ifdef CYG_HAL_USE_ROM_MONITOR_CYGMON +externC int +hal_diag_irq_check(int vector); + +#define HAL_DIAG_IRQ_CHECK(_vector_, _ret_) \ +CYG_MACRO_START \ +_ret_ = hal_diag_irq_check((_vector_)); \ +CYG_MACRO_END +#endif + //-------------------------------------------------------------------------- #endif // CYGONCE_HAL_VAR_ARCH_H // End of var_arch.h diff --git a/packages/hal/mips/tx39/current/include/variant.inc b/packages/hal/mips/tx39/current/include/variant.inc --- a/packages/hal/mips/tx39/current/include/variant.inc +++ b/packages/hal/mips/tx39/current/include/variant.inc @@ -157,10 +157,6 @@ .endm -#if defined(CYG_HAL_STARTUP_ROM) - - # Only do this in ROM configurations. - .macro hal_memc_init_dram # DRAM Configuration la v0, 0xffff8000 @@ -183,11 +179,6 @@ sw v1, 0(v0) .endm -#else - .macro hal_memc_init_dram - .endm -#endif - #define CYGPKG_HAL_MIPS_MEMC_DEFINED #endif @@ -201,12 +192,15 @@ # Set all ILRX registers to 0, masking all external interrupts. .macro hal_intc_init + +#ifndef CYG_HAL_STARTUP_RAM la v0,0xFFFFC010 move v1,zero sw v1,0(v0) sw v1,4(v0) sw v1,8(v0) sw v1,12(v0) +#endif .endm .macro hal_intc_decode vnum diff --git a/packages/hal/mips/tx39/current/src/hal_diag.c b/packages/hal/mips/tx39/current/src/hal_diag.c --- a/packages/hal/mips/tx39/current/src/hal_diag.c +++ b/packages/hal/mips/tx39/current/src/hal_diag.c @@ -55,10 +55,12 @@ /*---------------------------------------------------------------------------*/ //#define CYG_KERNEL_DIAG_LCD -#define CYG_KERNEL_DIAG_SERIAL0 +#define CYG_KERNEL_DIAG_SERIAL0 // For ROM start but see immediately below: -#if defined(CYG_HAL_USE_ROM_MONITOR) - +#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) +#undef CYG_KERNEL_DIAG_SERIAL0 +#undef CYG_KERNEL_DIAG_LCD +#define CYG_KERNEL_DIAG_CYGMON #define CYG_KERNEL_DIAG_GDB #endif @@ -85,7 +87,7 @@ void hal_diag_led(int x) /*---------------------------------------------------------------------------*/ -#ifdef CYG_KERNEL_DIAG_SERIAL0 +#if defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON) #define DIAG_BASE 0xfffff300 #define DIAG_SLCR (DIAG_BASE+0x00) @@ -192,7 +194,11 @@ void hal_diag_read_char_serial0(char *c) } +#if defined(CYG_KERNEL_DIAG_CYGMON) +void hal_diag_dumb_write_char(char c) +#else void hal_diag_write_char(char c) +#endif { #ifdef CYG_KERNEL_DIAG_GDB #if 0 //defined(CYG_HAL_USE_ROM_MONITOR) @@ -250,8 +256,12 @@ void hal_diag_write_char(char c) if( c1 == '+' ) break; - if( cyg_hal_is_break( &c1 , 1 ) ) - cyg_hal_user_break( NULL ); + { + extern void cyg_hal_user_break(CYG_ADDRWORD *regs); + extern cyg_bool cyg_hal_is_break(char *buf, int size); + if( cyg_hal_is_break( &c1 , 1 ) ) + cyg_hal_user_break( NULL ); + } break; } @@ -272,6 +282,7 @@ void hal_diag_write_char(char c) #endif } + void hal_diag_read_char(char *c) { for(;;) @@ -314,8 +325,263 @@ void hal_diag_read_char(char *c) } } +#endif // defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON) + + +#if defined(CYG_KERNEL_DIAG_CYGMON) // only + +/* This code has been imported from the BSP module. The definitions have + * been left as-is, even though there was scope for doing more, to avoid + * too much drift from the original sources + */ + +struct bsp_comm_procs { + void *ch_data; + void (*__write)(void *ch_data, const char *buf, int len); + int (*__read)(void *ch_data, char *buf, int len); + void (*__putc)(void *ch_data, char ch); + int (*__getc)(void *ch_data); + int (*__control)(void *ch_data, int func, ...); +}; + +// This is pointed to by entry BSP_NOTVEC_BSP_COMM_PROCS: +typedef struct { + int version; /* version number for future expansion */ + void *__ictrl_table; + void *__exc_table; + void *__dbg_vector; + void *__kill_vector; + struct bsp_comm_procs *__console_procs; + struct bsp_comm_procs *__debug_procs; + void *__flush_dcache; + void *__flush_icache; + void *__cpu_data; + void *__board_data; + void *__sysinfo; + int (*__set_debug_comm)(int __comm_id); + int (*__set_console_comm)(int __comm_id); + int (*__set_serial_baud)(int __comm_id, int baud); + void *__dbg_data; + void (*__reset)(void); + int __console_interrupt_flag; +} bsp_shared_t; + +/* + * Core Exception vectors. + */ +#define BSP_EXC_INT 0 +#define BSP_EXC_TLBMOD 1 +#define BSP_EXC_TLBL 2 +#define BSP_EXC_TLBS 3 +#define BSP_EXC_ADEL 4 +#define BSP_EXC_ADES 5 +#define BSP_EXC_IBE 6 +#define BSP_EXC_DBE 7 +#define BSP_EXC_SYSCALL 8 +#define BSP_EXC_BREAK 9 +#define BSP_EXC_ILL 10 +#define BSP_EXC_CPU 11 +#define BSP_EXC_OV 12 +#define BSP_EXC_TRAP 13 +#define BSP_EXC_VCEI 14 +#define BSP_EXC_FPE 15 +#define BSP_EXC_RSV16 16 +#define BSP_EXC_RSV17 17 +#define BSP_EXC_RSV18 18 +#define BSP_EXC_RSV19 19 +#define BSP_EXC_RSV20 20 +#define BSP_EXC_RSV21 21 +#define BSP_EXC_RSV22 22 +#define BSP_EXC_WATCH 23 +#define BSP_EXC_RSV24 24 +#define BSP_EXC_RSV25 25 +#define BSP_EXC_RSV26 26 +#define BSP_EXC_RSV27 27 +#define BSP_EXC_RSV28 28 +#define BSP_EXC_RSV29 29 +#define BSP_EXC_RSV30 30 +#define BSP_EXC_VCED 31 +/* tx39 debug exception */ +#define BSP_EXC_DEBUG 32 +#define BSP_EXC_TLB 33 +#define BSP_EXC_NMI 34 +/* + * Hack for eCos on tx39 to set an async breakpoint. + */ +#define BSP_VEC_BP_HOOK 35 + +#define BSP_EXC_XTLB 36 +#define BSP_EXC_CACHE 37 + +#define BSP_MAX_EXCEPTIONS 38 + +/* + * Another hack for tx39 eCos compatibility. + */ +#if defined(__CPU_R3900__) +#define BSP_VEC_MT_DEBUG 15 +#else +#define BSP_VEC_MT_DEBUG 38 #endif +#define BSP_VEC_STUB_ENTRY 39 +#define BSP_VEC_BSPDATA 40 +#define BSP_VEC_MAGIC 41 +#define BSP_VEC_IRQ_CHECK 42 + +#define BSP_VEC_PAD 43 +#define NUM_VTAB_ENTRIES 44 + + +#define BSP_MAGIC_VAL 0x55aa4321 + +#define SYS_interrupt 1000 + +// These vectors should be called with: +// +// k0 - Exception Number + +#define CYGMON_VECTOR_TABLE_BASE 0x80000100 +#define CYGMON_VECTOR_TABLE ((CYG_ADDRESS *)CYGMON_VECTOR_TABLE_BASE) + +#if 0 // UNUSED +static int +hal_bsp_set_debug_comm(int arg) +{ + bsp_shared_t *shared; + + shared = (bsp_shared_t *) + (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]); + + if (0 != shared->__set_debug_comm) { + return (*(shared->__set_debug_comm))(arg); + } + return 0; +} + +static int +hal_bsp_set_console_comm(int arg) +{ + bsp_shared_t *shared; + + shared = (bsp_shared_t *) + (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]); + + if (0 != shared->__set_console_comm) { + return (*(shared->__set_console_comm))(arg); + } + return 0; +} +#endif // 0 UNUSED + +static void bsp_trap(int trap_num); + +static int +hal_bsp_console_write(const void *p, int len) +{ + bsp_shared_t *shared; + struct bsp_comm_procs *com; + int magic; + + /*hal_bsp_set_console_comm(0);*/ + + /* If this is not a BSP-based CygMon, return 0 */ + magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]); + if (magic != BSP_MAGIC_VAL) + return 0; + + shared = (bsp_shared_t *) + (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]); + + com = shared->__console_procs; + + if (0 != com) { + shared->__console_interrupt_flag = 0; + com->__write(com->ch_data, p, len); + if (shared->__console_interrupt_flag) { + /* debug interrupt; stop here */ + bsp_trap(SYS_interrupt); + } + + return 1; + } + return 0; +} + +static void +bsp_trap(int trap_num) +{ + asm("syscall\n"); +} + + +static void +hal_dumb_serial_write(const char *p, int len) +{ + int i; + for ( i = 0 ; i < len; i++ ) { + hal_diag_dumb_write_char(p[i]); + } +} + +void hal_diag_write_char(char c) +{ + static char line[100]; + static int pos = 0; + + // No need to send CRs + if( c == '\r' ) return; + + line[pos++] = c; + + if( c == '\n' || pos == sizeof(line) ) { + CYG_INTERRUPT_STATE old; + + // Disable interrupts. This prevents GDB trying to interrupt us + // while we are in the middle of sending a packet. The serial + // receive interrupt will be seen when we re-enable interrupts + // later. + + HAL_DISABLE_INTERRUPTS(old); + + if ( ! hal_bsp_console_write( line, pos ) ) + // then there is no function registered, just spew it out serial + hal_dumb_serial_write( line, pos ); + + pos = 0; + + // And re-enable interrupts + HAL_RESTORE_INTERRUPTS(old); + + } +} + +int +hal_diag_irq_check(int vector) +{ + typedef int irq_check_fn(int irq_nr); + irq_check_fn *fn = (irq_check_fn *)(CYGMON_VECTOR_TABLE[ BSP_VEC_IRQ_CHECK ]); + int magic; + + + /* If this is not a BSP-based CygMon, return 0 */ + magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]); + if (magic != BSP_MAGIC_VAL) + return 0; + +#if defined(CYGPKG_HAL_MIPS_TX3904) + /* convert vector to BSP irq number */ + if (vector == 16) + vector = 2; + else + vector += 3; +#endif + + return fn(vector); +} + +#endif // defined(CYG_KERNEL_DIAG_CYGMON) *only* + /*---------------------------------------------------------------------------*/ #if defined(CYGPKG_HAL_MIPS_TX39_JMR3904) && defined(CYG_KERNEL_DIAG_LCD) diff --git a/packages/hal/powerpc/arch/current/ChangeLog b/packages/hal/powerpc/arch/current/ChangeLog --- a/packages/hal/powerpc/arch/current/ChangeLog +++ b/packages/hal/powerpc/arch/current/ChangeLog @@ -1,3 +1,14 @@ +1999-09-23 Jonathan Larmour + + * src/hal_misc.c (cyg_hal_exception_handler): Catch exceptions + generated from within the GDB stub so we can recover from bad memory + accesses + Also part of the fix for case 102104 + +1999-09-23 Jesper Skov + Case 102104 + * include/hal_cache.h (HAL_ICACHE_SYNC): Invalidate I cache. + 1999-09-06 Jesper Skov * src/hal_misc.c (hal_null_call): diff --git a/packages/hal/powerpc/arch/current/include/hal_cache.h b/packages/hal/powerpc/arch/current/include/hal_cache.h --- a/packages/hal/powerpc/arch/current/include/hal_cache.h +++ b/packages/hal/powerpc/arch/current/include/hal_cache.h @@ -475,7 +475,8 @@ externC cyg_memdesc_t cyg_hal_mem_map[]; "r" (CYGARC_REG_IC_CMD_IA)) // Synchronize the contents of the cache with memory. -#define HAL_ICACHE_SYNC() +#define HAL_ICACHE_SYNC() \ + HAL_ICACHE_INVALIDATE_ALL() // Query the state of the instruction cache #define HAL_ICACHE_IS_ENABLED(_state_) \ diff --git a/packages/hal/powerpc/arch/current/src/hal_misc.c b/packages/hal/powerpc/arch/current/src/hal_misc.c --- a/packages/hal/powerpc/arch/current/src/hal_misc.c +++ b/packages/hal/powerpc/arch/current/src/hal_misc.c @@ -103,11 +103,20 @@ externC void __handle_exception (void); externC HAL_SavedRegisters *_hal_registers; +externC void *__mem_fault_handler; + void cyg_hal_exception_handler(HAL_SavedRegisters *regs) { #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + // If we caught an exception inside the stubs, see if we were expecting it + // and if so jump to the saved address + if (__mem_fault_handler) { + regs->pc = (CYG_ADDRWORD)__mem_fault_handler; + return; // Caught an exception inside stubs + } + // Set the pointer to the registers of the current exception // context. At entry the GDB stub will expand the // HAL_SavedRegisters structure into a (bigger) register array. diff --git a/packages/hal/powerpc/arch/current/src/vectors.S b/packages/hal/powerpc/arch/current/src/vectors.S --- a/packages/hal/powerpc/arch/current/src/vectors.S +++ b/packages/hal/powerpc/arch/current/src/vectors.S @@ -378,7 +378,7 @@ 2: .extern hal_MMU_init bl hal_MMU_init - # Enable MMU it so we can safely enable caches. + # Enable MMU so we can safely enable caches. lwi r3,CYG_MSR_NO_INTS # interrupts enabled later sync mtmsr r3 diff --git a/packages/hal/powerpc/mbx/current/ChangeLog b/packages/hal/powerpc/mbx/current/ChangeLog --- a/packages/hal/powerpc/mbx/current/ChangeLog +++ b/packages/hal/powerpc/mbx/current/ChangeLog @@ -1,3 +1,19 @@ +1999-09-20 Hugo Tyson + + * include/pkgconf/hal_powerpc_mbx.h: + (CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH) new config option to + control chip select initialization. + + * src/mbx.S: Take notice of CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH. + + * misc/stubrom.perm: Reference the new option for folks who want + to boot from the 32-bit flash. + +1999-09-13 Gary Thomas + + * include/pkgconf/hal_powerpc_mbx.h (CYGHWR_HAL_POWERPC_BOARD_SPEED): + Missing default value (wouldn't build sans ConfigTool). + 1999-09-09 Gary Thomas * include/pkgconf/hal_powerpc_mbx.h (CYGHWR_HAL_POWERPC_MBX_BOARD_SPEED): diff --git a/packages/hal/powerpc/mbx/current/include/pkgconf/hal_powerpc_mbx.h b/packages/hal/powerpc/mbx/current/include/pkgconf/hal_powerpc_mbx.h --- a/packages/hal/powerpc/mbx/current/include/pkgconf/hal_powerpc_mbx.h +++ b/packages/hal/powerpc/mbx/current/include/pkgconf/hal_powerpc_mbx.h @@ -85,11 +85,29 @@ # setting it to 30, for example, would not work. } + cdl_option CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH { + display "Boot ROM is 32-bit Flash device" + parent CYGPKG_HAL_POWERPC_MBX + type boolean + description " + MBX Development Boards have a socketed 8-bit ROM (AM27F040, + AM29F040 or similar) and a permanently soldered 32-bit flash + device. Which is used for booting is link selectable (refer to + the MBX Series documentation from Motorola). Enable this option + when booting from the 32-bit flash so that the correct memory + timing and access method is initialized. This consideration + does apply to RAM start eCos applications as well as ROM start + or stub ROMs." + } + }}CFG_DATA */ #define CYGHWR_HAL_POWERPC_MBX_STARTUP ram -#define CYGHWR_HAL_POWERPC_MBX_BOARD_SPEED 50 +#define CYGHWR_HAL_POWERPC_BOARD_SPEED 50 + +// Normally, the 8-bit socketed ROM is used +#undef CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH // Real-time clock/counter specifics diff --git a/packages/hal/powerpc/mbx/current/misc/stubrom.perm b/packages/hal/powerpc/mbx/current/misc/stubrom.perm --- a/packages/hal/powerpc/mbx/current/misc/stubrom.perm +++ b/packages/hal/powerpc/mbx/current/misc/stubrom.perm @@ -8,6 +8,11 @@ # Where is the path to your source repository. # (If necessary, make sure the system clock speed is set correctly in # pkgconf/hal_powerpc_mbx.h: 40MHz (MPC821) versus 50MHz (MPC860) by default) +# If you do not have permtest, use the config tool or an editor to make +# the changes listed below to the relevant configuration files. +# If you intend to install the image into the 32-bit flash device instead of +# the 8-bit socketed ROM, set the option CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH +# in hal_powerpc_mbx.h # 3. Run: make # 4. Run: make -C hal/common/current/src/stubrom # diff --git a/packages/hal/powerpc/mbx/current/src/mbx.S b/packages/hal/powerpc/mbx/current/src/mbx.S --- a/packages/hal/powerpc/mbx/current/src/mbx.S +++ b/packages/hal/powerpc/mbx/current/src/mbx.S @@ -262,9 +262,14 @@ FUNC_START( hal_hardware_init ) #else lwi r5,0xff800930 #endif +#ifdef CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH + // Then the 32-bit FLASH device is on CS0, the "ROM" is on CS7 + stw r3,BR7(r4) + stw r5,OR7(r4) +#else // Boot from 8-bit ROM - the default, on CS0 stw r3,BR0(r4) stw r5,OR0(r4) - +#endif /* ONBOARD DRAM */ lwi r3,0x00000081 # 32-bit, UPMA lwi r5,0xffc00400 @@ -312,9 +317,14 @@ FUNC_START( hal_hardware_init ) #else lwi r5,0xff800930 #endif +#ifdef CYGHWR_HAL_POWERPC_MBX_BOOT_32BIT_FLASH + // Then the 32-bit FLASH device is on CS0, the "ROM" is on CS7 + stw r3,BR0(r4) + stw r5,OR0(r4) +#else // Boot from 8-bit ROM - so the 32-bit FLASH is on CS7 stw r3,BR7(r4) stw r5,OR7(r4) - +#endif /* * SYSTEM CLOCK CONTROL REGISTER * diff --git a/packages/hal/powerpc/sim/current/ChangeLog b/packages/hal/powerpc/sim/current/ChangeLog --- a/packages/hal/powerpc/sim/current/ChangeLog +++ b/packages/hal/powerpc/sim/current/ChangeLog @@ -1,3 +1,7 @@ +1999-09-23 Jonathan Larmour + + * runtime/tree: Delete. Now obsolete. + 1999-06-11 Hugo Tyson * src/PKGconf.mak: Build the new file. diff --git a/packages/hal/powerpc/sim/current/runtime/tree b/packages/hal/powerpc/sim/current/runtime/tree deleted file mode 100644 --- a/packages/hal/powerpc/sim/current/runtime/tree +++ /dev/null @@ -1,5 +0,0 @@ -/#address-cells 1 -/openprom/init/register/pc 0x100 -/iobus@0xf0000000/reg 0xf0000000 0x01000000 -/iobus/pal@0xf0001000/reg 0xf0001000 32 - diff --git a/packages/io/serial/current/src/PKGconf.mak b/packages/io/serial/current/src/PKGconf.mak --- a/packages/io/serial/current/src/PKGconf.mak +++ b/packages/io/serial/current/src/PKGconf.mak @@ -40,7 +40,7 @@ endif ifdef CYG_HAL_ARM_AEB EXTRAS_COMPILE += arm/aeb_serial.c endif -ifdef CYG_HAL_ARM_CL7211 +ifdef CYG_HAL_ARM_EB7211 EXTRAS_COMPILE += arm/cl7211_serial.c endif ifdef CYG_HAL_MN10300_AM31 diff --git a/packages/kernel/current/ChangeLog b/packages/kernel/current/ChangeLog --- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,25 @@ +1999-09-16 Hugo Tyson + + * tests/tm_basic.cxx (run_mutex_tests): Must unlock mutices before + destroying, given the change below. + + * src/common/kapi.cxx (cyg_cond_destroy): Call the correct + destructor. As it happens, it didn't matter because all these + destructors do is assert the queue is empty, and the queue is the + 2nd word in every case. + (cyg_mutex_destroy): Call the destructor at all, so that + assertions are made. + +1999-09-13 Gary Thomas + + * src/intr/intr.cxx (call_pending_DSRs_inner): Add assert to check + for valid DSR (before trying to use it). + +1999-09-13 Jesper Skov + + * tests/stress_threads.c: Print out malloc system info. + (print_statistics): Fix buglet. + 1999-09-10 Jesper Skov * tests/stress_threads.c: Print out more info. Reduce dump diff --git a/packages/kernel/current/src/common/kapi.cxx b/packages/kernel/current/src/common/kapi.cxx --- a/packages/kernel/current/src/common/kapi.cxx +++ b/packages/kernel/current/src/common/kapi.cxx @@ -1005,7 +1005,7 @@ externC void cyg_mutex_init( externC void cyg_mutex_destroy( cyg_mutex_t *mutex ) { - // no need to do anything here + ((Cyg_Mutex *)mutex)->~Cyg_Mutex(); } externC cyg_bool_t cyg_mutex_lock( cyg_mutex_t *mutex ) @@ -1045,7 +1045,7 @@ externC void cyg_cond_init( externC void cyg_cond_destroy( cyg_cond_t *cond ) { - ((Cyg_Counting_Semaphore *)cond)->~Cyg_Counting_Semaphore(); + ((Cyg_Condition_Variable *)cond)->~Cyg_Condition_Variable(); } externC void cyg_cond_wait( cyg_cond_t *cond ) diff --git a/packages/kernel/current/src/intr/intr.cxx b/packages/kernel/current/src/intr/intr.cxx --- a/packages/kernel/current/src/intr/intr.cxx +++ b/packages/kernel/current/src/intr/intr.cxx @@ -147,6 +147,8 @@ Cyg_Interrupt::call_pending_DSRs_inner(v CYG_INSTRUMENT_INTR(CALL_DSR, intr->vector, 0); + CYG_ASSERT( intr->dsr != NULL , "No DSR defined"); + intr->dsr( intr->vector, 1, (CYG_ADDRWORD)intr->data ); } @@ -168,6 +170,8 @@ Cyg_Interrupt::call_pending_DSRs_inner(v intr->dsr_count = 0; HAL_RESTORE_INTERRUPTS(old_intr); + + CYG_ASSERT( intr->dsr != NULL , "No DSR defined"); intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data ); diff --git a/packages/kernel/current/tests/stress_threads.c b/packages/kernel/current/tests/stress_threads.c --- a/packages/kernel/current/tests/stress_threads.c +++ b/packages/kernel/current/tests/stress_threads.c @@ -165,16 +165,23 @@ volatile int free_handler_pri = 0; volatile int free_handler_id = -1; /* a global variable with which the client and server coordinate */ -int client_makes_request = 0; +volatile int client_makes_request = 0; + +/* if this is true, clients will not make requests */ +volatile int clients_paused = 0; + /* indicates that it's time to print out a report */ -int time_to_report = 0; +volatile int time_to_report = 0; /* print status after a delay of this many secs. */ int time_report_delay; /*** now application-specific variables ***/ /* an array that stores whether the handler threads are in use */ -int handler_thread_in_use[MAX_HANDLERS]; +volatile int handler_thread_in_use[MAX_HANDLERS]; +/* total count of active handlers */ +volatile int handler_thread_in_use_count; + /***** statistics-gathering variables *****/ struct s_statistics { @@ -204,7 +211,8 @@ void sc_thread_create( cyg_thread *thread /* put thread here */ ); -int get_handler_slot(cyg_handle_t current_threadH); +void start_handler(void); +void stop_handler(int handler_id, int handler_pri); void perform_stressful_tasks(void); void permute_array(char a[], int size, int seed); void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, @@ -251,6 +259,7 @@ main(void) for (i = 0; i < MAX_HANDLERS; ++i) { handler_thread_in_use[i] = 0; } + handler_thread_in_use_count = 0; for (i = 0; i < N_LISTENERS; ++i) { int prio = P_BASE_LISTENER + i; char* name = &thread_name[prio][0]; @@ -327,34 +336,34 @@ void main_program(cyg_addrword_t data) } cyg_mutex_unlock(&free_handler_lock); if (-1 != handler_id) { - // Free the handler resources. This is done outside of the - // free_handler_lock to avoid deadlocks. - cyg_mutex_lock(&handler_slot_lock); { - CYG_ASSERT(1 == priority_in_use[handler_pri], - "Priority not in use!"); - CYG_ASSERT(1 == handler_thread_in_use[handler_id], - "Handler not in use!"); - handler_thread_in_use[handler_id]--; - priority_in_use[handler_pri]--; - - // Finally delete the handler thread. This must be done in a - // loop, waiting for the call to return true. If it returns - // false, go to sleep for a bit, so the killed thread gets a - // chance to run and complete its business. - while (!cyg_thread_delete(handlerH[handler_id])) { - cyg_thread_delay(2); - } - } cyg_mutex_unlock(&handler_slot_lock); + stop_handler(handler_id, handler_pri); } - // Print status if time. + // If it's time to report status or quit, set pause flag and + // keep looping until all handlers have stopped. if (time_to_report) { - time_to_report = 0; - print_statistics(0); + // Pause clients + cyg_mutex_lock(&client_request_lock); { + clients_paused = 1; + } cyg_mutex_unlock(&client_request_lock); + + // When all handlers have stopped, we can print statistics + // knowing that all (handler allocated) resources should have + // been freed. That is, we should be able to determine leaks. + if (0 == handler_thread_in_use_count) { + print_statistics(0); + + // We've done the printing now. Resume the system. + time_to_report = 0; + cyg_mutex_lock(&client_request_lock); { + clients_paused = 0; + } cyg_mutex_unlock(&client_request_lock); + } } #ifdef DEATH_TIME_LIMIT - // Stop test if time. + // Stop test if time. We don't care about resource state here + // since we've only run for a limited time anyway. if (is_dead) { print_statistics(1); CYG_TEST_PASS_FINISH("Kernel thread stress test OK"); @@ -378,7 +387,8 @@ void client_program(cyg_addrword_t data) /* now send a request to the server */ cyg_mutex_lock(&client_request_lock); { - ++client_makes_request; + if (0 == clients_paused) + client_makes_request++; } cyg_mutex_unlock(&client_request_lock); cyg_thread_delay(10+delay); @@ -389,9 +399,6 @@ void client_program(cyg_addrword_t data) take care of the request */ void listener_program(cyg_addrword_t data) { -/* int message = (int) data; */ - int handler_slot; - for (;;) { int make_request = 0; cyg_mutex_lock(&client_request_lock); { @@ -401,27 +408,9 @@ void listener_program(cyg_addrword_t dat } } cyg_mutex_unlock(&client_request_lock); - if (make_request) { - int prio; - char* name; - - handler_slot = get_handler_slot(listenerH[(int) data]); - prio = P_BASE_HANDLER+handler_slot; - - name = &thread_name[prio][0]; - sprintf(name, "handler-%02d/%02d", handler_slot, prio); - - CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); - priority_in_use[prio]++; - sc_thread_create(prio, handler_program, - (cyg_addrword_t) handler_slot, - name, (void *) handler_stack[handler_slot], - STACK_SIZE_HANDLER, &handlerH[handler_slot], - &handler_thread_s[handler_slot]); - cyg_thread_resume(handlerH[handler_slot]); - ++statistics.handler_invocation_histogram[handler_slot]; - } - + if (make_request) + start_handler(); + cyg_thread_delay(2 + (rand() % 10)); } } @@ -434,7 +423,6 @@ void handler_program(cyg_addrword_t data cyg_thread_delay(4 + (int) (0.5*log(1.0 + fabs((rand() % 1000000))))); - ++statistics.thread_exits; { // Loop until the handler id and priority can be communicated to // the main_program. @@ -456,18 +444,21 @@ void handler_program(cyg_addrword_t data cyg_thread_exit(); } -/* look for an available handler thread */ -int get_handler_slot(cyg_handle_t current_threadH) +/* start a new handler */ +void start_handler(void) { - int i; + int prio; + char* name; + int handler_slot; int found = 0; while (!found) { cyg_mutex_lock(&handler_slot_lock); { - for (i = 0; i < MAX_HANDLERS; ++i) { - if (!handler_thread_in_use[i]) { + for (handler_slot = 0; handler_slot < MAX_HANDLERS;++handler_slot){ + if (!handler_thread_in_use[handler_slot]) { found = 1; - handler_thread_in_use[i]++; + handler_thread_in_use[handler_slot]++; + handler_thread_in_use_count++; break; } } @@ -476,27 +467,66 @@ int get_handler_slot(cyg_handle_t curren cyg_thread_delay(1); } - CYG_ASSERT(1 == handler_thread_in_use[i], "Handler usage count wrong!"); + CYG_ASSERT(1 == handler_thread_in_use[handler_slot], + "Handler usage count wrong!"); + + prio = P_BASE_HANDLER+handler_slot; + CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); + priority_in_use[prio]++; + + name = &thread_name[prio][0]; + sprintf(name, "handler-%02d/%02d", handler_slot, prio); + + sc_thread_create(prio, handler_program, + (cyg_addrword_t) handler_slot, + name, (void *) handler_stack[handler_slot], + STACK_SIZE_HANDLER, &handlerH[handler_slot], + &handler_thread_s[handler_slot]); + cyg_thread_resume(handlerH[handler_slot]); + ++statistics.handler_invocation_histogram[handler_slot]; +} - return i; +/* free a locked handler thread */ +void stop_handler(int handler_id, int handler_pri) +{ + // Finally delete the handler thread. This must be done in a + // loop, waiting for the call to return true. If it returns + // false, go to sleep for a bit, so the killed thread gets a + // chance to run and complete its business. + while (!cyg_thread_delete(handlerH[handler_id])) { + cyg_thread_delay(1); + } + ++statistics.thread_exits; + + // Free the handler resources. + cyg_mutex_lock(&handler_slot_lock); { + handler_thread_in_use[handler_id]--; + handler_thread_in_use_count--; + priority_in_use[handler_pri]--; + CYG_ASSERT(0 == priority_in_use[handler_pri], + "Priority not in use!"); + CYG_ASSERT(0 == handler_thread_in_use[handler_id], + "Handler not in use!"); + CYG_ASSERT(0 <= handler_thread_in_use_count, + "Stopped more handlers than was started!"); + } cyg_mutex_unlock(&handler_slot_lock); + } + /* do things which will stress the system */ void perform_stressful_tasks() { #define MAX_MALLOCED_SPACES 100 /* do this many mallocs at most */ #define MALLOCED_BASE_SIZE 1 /* basic size in bytes */ char *spaces[MAX_MALLOCED_SPACES]; - unsigned int i; - - cyg_mutex_t tmp_lock; + int sizes[MAX_MALLOCED_SPACES]; + unsigned int i, j, size; cyg_uint8 pool_space[10][100]; cyg_handle_t mempool_handles[10]; cyg_mempool_fix mempool_objects[10]; - cyg_mutex_init(&tmp_lock); - /* here I use malloc, which uses the kernel's variable memory pools. note that malloc/free is a bit simple-minded here: it does not try to really fragment things, and it does not try to make the @@ -504,8 +534,17 @@ void perform_stressful_tasks() (although I'm about to throw in a yield()) */ for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { ++statistics.malloc_tries; -/* spaces[i] = (char *) malloc(((int)(sqrt(i*2.0))+1)*MALLOCED_BASE_SIZE); */ - spaces[i] = (char *) malloc(((int)i*2.0+1)*MALLOCED_BASE_SIZE); + size = (i*2+1)*MALLOCED_BASE_SIZE; + spaces[i] = (char *) malloc(size); + sizes[i] = size; + + if (spaces[i] != NULL) { + // Fill with a known value (differs between chunk). + for (j = 0; j < size; ++j) { + spaces[i][j] = 0x50 | ((j+i) & 0x0f); + } + } + if (i % (MAX_MALLOCED_SPACES/10) == 0) { cyg_thread_yield(); } @@ -514,11 +553,17 @@ void perform_stressful_tasks() } } + cyg_thread_delay(5); + /* now free it all up */ for (i = 0; i < MAX_MALLOCED_SPACES; ++i) { if (spaces[i] != NULL) { - unsigned int j; - for (j = 0; j < (i*2+1)*MALLOCED_BASE_SIZE; ++j) { + size = sizes[i]; + for (j = 0; j < size; ++j) { + // Validate chunk data. + if ((0x50 | ((j+i) & 0x0f)) != spaces[i][j]) { + printf("Bad byte in chunk\n"); + } spaces[i][j] = 0xAA; /* write a bit pattern */ } free(spaces[i]); @@ -526,6 +571,7 @@ void perform_stressful_tasks() ++statistics.malloc_failures; } } + /* now allocate and then free some fixed-size memory pools; for now this is simple-minded because it does not have many threads sharing the memory pools and racing for memory. */ @@ -543,8 +589,6 @@ void perform_stressful_tasks() cyg_mempool_fix_delete(mempool_handles[i]); } } - - cyg_mutex_destroy(&tmp_lock); } /* report_alarm_func() is invoked as an alarm handler, so it should be @@ -622,7 +666,7 @@ void sc_thread_create( #define MINS_HOUR (60) #define MINS_DAY (60*24) -externC void *cyg_libc_get_pool( void ); +externC void *cyg_libc_get_malloc_pool( void ); void print_statistics(int print_full) { @@ -660,7 +704,8 @@ void print_statistics(int print_full) } printf("\nState dump %d (%d hours, %d minutes) [numbers >>%d]\n", - ++print_count, minutes / MINS_HOUR, minutes, shift_count); + ++print_count, minutes / MINS_HOUR, minutes % MINS_HOUR, + shift_count); cyg_mutex_lock(&statistics_print_lock); { //-------------------------------- @@ -683,24 +728,18 @@ void print_statistics(int print_full) statistics.malloc_tries >>= 1; statistics.malloc_failures >>= 1; } + } cyg_mutex_unlock(&statistics_print_lock); - //-------------------------------- - // System information -#if 0 - // We want to (occasionally) pause the test so all memory is - // freed. Otherwise it's hard to tell if there's a malloc - // leak. - { - cyg_mempool_info mem_info; + //-------------------------------- + // System information + { + cyg_mempool_info mem_info; - cyg_mempool_var_get_info((cyg_handle_t) cyg_libc_get_pool(), - &mem_info); - printf(" Memory system: Total=0x%08x Free=0x%08x Max=0x%08x\n", - mem_info.totalmem, mem_info.freemem, mem_info.maxfree); - } -#endif - - } cyg_mutex_unlock(&statistics_print_lock); + cyg_mempool_var_get_info((cyg_handle_t) cyg_libc_get_malloc_pool(), + &mem_info); + printf(" Memory system: Total=0x%08x Free=0x%08x Max=0x%08x\n", + mem_info.totalmem, mem_info.freemem, mem_info.maxfree); + } // Dump stack status printf(" Stack usage:\n"); diff --git a/packages/kernel/current/tests/tm_basic.cxx b/packages/kernel/current/tests/tm_basic.cxx --- a/packages/kernel/current/tests/tm_basic.cxx +++ b/packages/kernel/current/tests/tm_basic.cxx @@ -744,6 +744,11 @@ run_mutex_tests(void) } show_times(mutex_ft, nmutexes, "Trylock [locked] mutex"); + // Must unlock mutices before destroying them. + for (i = 0; i < nmutexes; i++) { + cyg_mutex_unlock(&test_mutexes[i]); + } + wait_for_tick(); // Wait until the next clock tick to minimize aberations for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); diff --git a/packages/language/c/libc/current/ChangeLog b/packages/language/c/libc/current/ChangeLog --- a/packages/language/c/libc/current/ChangeLog +++ b/packages/language/c/libc/current/ChangeLog @@ -1,3 +1,8 @@ +1999-09-15 Jesper Skov + + * tests/signal/signal2.c (cause_fpe): Try both float and integer + division by zero. + 1999-09-10 Jesper Skov * src/stdlib/malloc.cxx (cyg_libc_get_malloc_pool): Added for diff --git a/packages/language/c/libc/current/tests/signal/signal2.c b/packages/language/c/libc/current/tests/signal/signal2.c --- a/packages/language/c/libc/current/tests/signal/signal2.c +++ b/packages/language/c/libc/current/tests/signal/signal2.c @@ -108,10 +108,19 @@ cause_memerror(void) // num must always be 0 - do it this way in case the optimizer tries to // get smart -static double +static int cause_fpe(int num) { - return 1.0/num; + double a; + + a = 1.0/num; // Depending on FPU emulation and/or + // the FPU architecture, this may + // cause an exception. + // (float division by zero) + + return ((int)a)/num; // This may cause an exception if + // the architecture supports it. + // (integer division by zero). } // cause_fpe() #endif