Changeset 6ac14a70 in mainline for kernel/arch/arm32


Ignore:
Timestamp:
2009-07-28T12:47:31Z (16 years ago)
Author:
Vineeth Pillai <vineethrp@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5e73815
Parents:
7038f55
Message:

ARM port for development board integratorcp(ARM926EJ core module).

Location:
kernel/arch/arm32
Files:
6 added
7 edited
1 moved

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/Makefile.inc

    r7038f55 r6ac14a70  
    4646        arch/$(KARCH)/src/start.S \
    4747        arch/$(KARCH)/src/asm.S \
     48        arch/$(KARCH)/src/exc_handler.S \
    4849        arch/$(KARCH)/src/arm32.c \
     50        arch/$(KARCH)/src/machine_func.c \
    4951        arch/$(KARCH)/src/context.S \
    5052        arch/$(KARCH)/src/dummy.S \
     
    5961        arch/$(KARCH)/src/mm/page.c \
    6062        arch/$(KARCH)/src/mm/tlb.c \
    61         arch/$(KARCH)/src/mm/page_fault.c \
    62         arch/$(KARCH)/src/drivers/gxemul.c
     63        arch/$(KARCH)/src/mm/page_fault.c
     64ifeq ($(MACHINE), testarm)
     65        ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c
     66else ifeq ($(MACHINE), integratorcp)
     67        ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c
     68endif
     69ifeq ($(CONFIG_PL050), y)
     70        ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c
     71endif
  • kernel/arch/arm32/include/exception.h

    r7038f55 r6ac14a70  
    137137extern void exception_init(void);
    138138extern void print_istate(istate_t *istate);
     139extern void reset_exception_entry(void);
     140extern void irq_exception_entry(void);
     141extern void fiq_exception_entry(void);
     142extern void undef_instr_exception_entry(void);
     143extern void prefetch_abort_exception_entry(void);
     144extern void data_abort_exception_entry(void);
     145extern void swi_exception_entry(void);
    139146
    140147
  • kernel/arch/arm32/include/mach/testarm/testarm.h

    r7038f55 r6ac14a70  
    11/*
    22 * Copyright (c) 2007 Michal Kebrt
     3 * Copyright (c) 2009 Vineeth Pillai
    34 * All rights reserved.
    45 *
     
    3940#define KERN_arm32_GXEMUL_H_
    4041
     42#include <arch/machine_func.h>
     43
    4144/** Last interrupt number (beginning from 0) whose status is probed
    4245 * from interrupt controller
     
    6568
    6669extern void gxemul_init(void);
     70extern void gxemul_fb_init(void);
     71extern void gxemul_output_init(void);
     72extern void gxemul_input_init(void);
     73extern void gxemul_release_console(void);
     74extern void gxemul_grab_console(void);
     75extern void gxemul_timer_irq_start(void);
     76extern void gxemul_cpu_halt(void);
     77extern void gxemul_irq_exception(int exc_no, istate_t *istate);
     78extern uintptr_t gxemul_get_memory_size(void);
     79extern uintptr_t gxemul_get_fb_address(void);
     80extern void gxemul_fb_init(void);
     81extern void gxemul_frame_init(void);
     82
    6783
    6884#endif
  • kernel/arch/arm32/src/arm32.c

    r7038f55 r6ac14a70  
    3838#include <genarch/fb/fb.h>
    3939#include <genarch/fb/visuals.h>
    40 #include <genarch/drivers/dsrln/dsrlnin.h>
    41 #include <genarch/drivers/dsrln/dsrlnout.h>
    42 #include <genarch/srln/srln.h>
    4340#include <sysinfo/sysinfo.h>
    4441#include <console/console.h>
    4542#include <ddi/irq.h>
    46 #include <arch/drivers/gxemul.h>
     43#include <arch/machine.h>
    4744#include <print.h>
    4845#include <config.h>
     
    7875void arch_post_mm_init(void)
    7976{
    80         gxemul_init();
     77        machine_init();
    8178       
    8279        /* Initialize exception dispatch table */
     
    8582       
    8683#ifdef CONFIG_FB
    87         fb_properties_t prop = {
    88                 .addr = GXEMUL_FB_ADDRESS,
    89                 .offset = 0,
    90                 .x = 640,
    91                 .y = 480,
    92                 .scan = 1920,
    93                 .visual = VISUAL_BGR_8_8_8,
    94         };
    95         fb_init(&prop);
     84        machine_fb_init();
    9685#else
    9786#ifdef CONFIG_ARM_PRN
    98         dsrlnout_init((ioport8_t *) gxemul_kbd);
     87        machine_output_init();
    9988#endif /* CONFIG_ARM_PRN */
    10089#endif /* CONFIG_FB */
     
    127116void arch_post_smp_init(void)
    128117{
    129 #ifdef CONFIG_ARM_KBD
    130         /*
    131          * Initialize the GXemul keyboard port. Then initialize the serial line
    132          * module and connect it to the GXemul keyboard.
    133          */
    134         dsrlnin_instance_t *dsrlnin_instance
    135             = dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
    136         if (dsrlnin_instance) {
    137                 srln_instance_t *srln_instance = srln_init();
    138                 if (srln_instance) {
    139                         indev_t *sink = stdin_wire();
    140                         indev_t *srln = srln_wire(srln_instance, sink);
    141                         dsrlnin_wire(dsrlnin_instance, srln);
    142                 }
    143         }
    144        
    145         /*
    146          * This is the necessary evil until the userspace driver is entirely
    147          * self-sufficient.
    148          */
    149         sysinfo_set_item_val("kbd", NULL, true);
    150         sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
    151         sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
    152 #endif
     118        machine_input_init();
    153119}
    154120
     
    157123void before_task_runs_arch(void)
    158124{
    159         tlb_invalidate_all();
    160125}
    161126
     
    169134        uint8_t *stck;
    170135       
     136        tlb_invalidate_all();
    171137        stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
    172138        supervisor_sp = (uintptr_t) stck;
     
    184150void cpu_halt(void)
    185151{
    186         *((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
    187                 = 0;
     152        machine_cpu_halt();
    188153}
    189154
     
    212177void arch_grab_console(void)
    213178{
     179        machine_grab_console();
    214180#ifdef CONFIG_FB
    215181        fb_redraw();
     
    220186void arch_release_console(void)
    221187{
     188        machine_release_console();
    222189}
    223190
  • kernel/arch/arm32/src/exception.c

    r7038f55 r6ac14a70  
    4040#include <arch/mm/page_fault.h>
    4141#include <arch/barrier.h>
    42 #include <arch/drivers/gxemul.h>
     42#include <arch/machine.h>
    4343#include <print.h>
    4444#include <syscall/syscall.h>
     
    5858/** Size of memory block occupied by exception vectors. */
    5959#define EXC_VECTORS_SIZE     (EXC_VECTORS * 4)
    60 
    61 /** Switches to kernel stack and saves all registers there.
    62  *
    63  * Temporary exception stack is used to save a few registers
    64  * before stack switch takes place.
    65  *
    66  */
    67 inline static void setup_stack_and_save_regs()
    68 {
    69         asm volatile (
    70                 "ldr r13, =exc_stack\n"
    71                 "stmfd r13!, {r0}\n"
    72                 "mrs r0, spsr\n"
    73                 "and r0, r0, #0x1f\n"
    74                 "cmp r0, #0x10\n"
    75                 "bne 1f\n"
    76                
    77                 /* prev mode was usermode */
    78                 "ldmfd r13!, {r0}\n"
    79                 "ldr r13, =supervisor_sp\n"
    80                 "ldr r13, [r13]\n"
    81                 "stmfd r13!, {lr}\n"
    82                 "stmfd r13!, {r0-r12}\n"
    83                 "stmfd r13!, {r13, lr}^\n"
    84                 "mrs r0, spsr\n"
    85                 "stmfd r13!, {r0}\n"
    86                 "b 2f\n"
    87                
    88                 /* mode was not usermode */
    89                 "1:\n"
    90                         "stmfd r13!, {r1, r2, r3}\n"
    91                         "mrs r1, cpsr\n"
    92                         "mov r2, lr\n"
    93                         "bic r1, r1, #0x1f\n"
    94                         "orr r1, r1, r0\n"
    95                         "mrs r0, cpsr\n"
    96                         "msr cpsr_c, r1\n"
    97                        
    98                         "mov r3, r13\n"
    99                         "stmfd r13!, {r2}\n"
    100                         "mov r2, lr\n"
    101                         "stmfd r13!, {r4-r12}\n"
    102                         "mov r1, r13\n"
    103                        
    104                         /* the following two lines are for debugging */
    105                         "mov sp, #0\n"
    106                         "mov lr, #0\n"
    107                         "msr cpsr_c, r0\n"
    108                        
    109                         "ldmfd r13!, {r4, r5, r6, r7}\n"
    110                         "stmfd r1!, {r4, r5, r6}\n"
    111                         "stmfd r1!, {r7}\n"
    112                         "stmfd r1!, {r2}\n"
    113                         "stmfd r1!, {r3}\n"
    114                         "mrs r0, spsr\n"
    115                         "stmfd r1!, {r0}\n"
    116                         "mov r13, r1\n"
    117                        
    118                 "2:\n"
    119         );
    120 }
    121 
    122 /** Returns from exception mode.
    123  *
    124  * Previously saved state of registers (including control register)
    125  * is restored from the stack.
    126  */
    127 inline static void load_regs()
    128 {
    129         asm volatile(
    130                 "ldmfd r13!, {r0}               \n"
    131                 "msr spsr, r0                   \n"
    132                 "and r0, r0, #0x1f              \n"
    133                 "cmp r0, #0x10                  \n"
    134                 "bne 1f                         \n"
    135 
    136                 /* return to user mode */
    137                 "ldmfd r13!, {r13, lr}^         \n"
    138                 "b 2f                           \n"
    139 
    140                 /* return to non-user mode */
    141         "1:\n"
    142                 "ldmfd r13!, {r1, r2}           \n"
    143                 "mrs r3, cpsr                   \n"
    144                 "bic r3, r3, #0x1f              \n"
    145                 "orr r3, r3, r0                 \n"
    146                 "mrs r0, cpsr                   \n"
    147                 "msr cpsr_c, r3                 \n"
    148 
    149                 "mov r13, r1                    \n"
    150                 "mov lr, r2                     \n"
    151                 "msr cpsr_c, r0                 \n"
    152 
    153                 /* actual return */
    154         "2:\n"
    155                 "ldmfd r13, {r0-r12, pc}^\n"
    156         );
    157 }
    158 
    159 
    160 /** Switch CPU to mode in which interrupts are serviced (currently it
    161  * is Undefined mode).
    162  *
    163  * The default mode for interrupt servicing (Interrupt Mode)
    164  * can not be used because of nested interrupts (which can occur
    165  * because interrupts are enabled in higher levels of interrupt handler).
    166  */
    167 inline static void switch_to_irq_servicing_mode()
    168 {
    169         /* switch to Undefined mode */
    170         asm volatile(
    171                 /* save regs used during switching */
    172                 "stmfd sp!, {r0-r3}             \n"
    173 
    174                 /* save stack pointer and link register to r1, r2 */
    175                 "mov r1, sp                     \n"
    176                 "mov r2, lr                     \n"
    177 
    178                 /* mode switch */
    179                 "mrs r0, cpsr                   \n"
    180                 "bic r0, r0, #0x1f              \n"
    181                 "orr r0, r0, #0x1b              \n"
    182                 "msr cpsr_c, r0                 \n"
    183 
    184                 /* restore saved sp and lr */
    185                 "mov sp, r1                     \n"
    186                 "mov lr, r2                     \n"
    187 
    188                 /* restore original regs */
    189                 "ldmfd sp!, {r0-r3}             \n"
    190         );
    191 }
    192 
    193 /** Calls exception dispatch routine. */
    194 #define CALL_EXC_DISPATCH(exception) \
    195         asm volatile ( \
    196                 "mov r0, %[exc]\n" \
    197                 "mov r1, r13\n" \
    198                 "bl exc_dispatch\n" \
    199                 :: [exc] "i" (exception) \
    200         );\
    201 
    202 /** General exception handler.
    203  *
    204  *  Stores registers, dispatches the exception,
    205  *  and finally restores registers and returns from exception processing.
    206  *
    207  *  @param exception Exception number.
    208  */
    209 #define PROCESS_EXCEPTION(exception) \
    210         setup_stack_and_save_regs(); \
    211         CALL_EXC_DISPATCH(exception) \
    212         load_regs();
    21360
    21461/** Updates specified exception vector to jump to given handler.
     
    23380}
    23481
    235 /** Low-level Reset Exception handler. */
    236 static void reset_exception_entry(void)
    237 {
    238         PROCESS_EXCEPTION(EXC_RESET);
    239 }
    240 
    241 /** Low-level Software Interrupt Exception handler. */
    242 static void swi_exception_entry(void)
    243 {
    244         PROCESS_EXCEPTION(EXC_SWI);
    245 }
    246 
    247 /** Low-level Undefined Instruction Exception handler. */
    248 static void undef_instr_exception_entry(void)
    249 {
    250         PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
    251 }
    252 
    253 /** Low-level Fast Interrupt Exception handler. */
    254 static void fiq_exception_entry(void)
    255 {
    256         PROCESS_EXCEPTION(EXC_FIQ);
    257 }
    258 
    259 /** Low-level Prefetch Abort Exception handler. */
    260 static void prefetch_abort_exception_entry(void)
    261 {
    262         asm volatile (
    263                 "sub lr, lr, #4"
    264         );
    265        
    266         PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
    267 }
    268 
    269 /** Low-level Data Abort Exception handler. */
    270 static void data_abort_exception_entry(void)
    271 {
    272         asm volatile (
    273                 "sub lr, lr, #8"
    274         );
    275        
    276         PROCESS_EXCEPTION(EXC_DATA_ABORT);
    277 }
    278 
    279 /** Low-level Interrupt Exception handler.
    280  *
    281  * CPU is switched to Undefined mode before further interrupt processing
    282  * because of possible occurence of nested interrupt exception, which
    283  * would overwrite (and thus spoil) stack pointer.
    284  */
    285 static void irq_exception_entry(void)
    286 {
    287         asm volatile (
    288                 "sub lr, lr, #4"
    289         );
    290        
    291         setup_stack_and_save_regs();
    292        
    293         switch_to_irq_servicing_mode();
    294        
    295         CALL_EXC_DISPATCH(EXC_IRQ)
    296 
    297         load_regs();
    298 }
    299 
    30082/** Software Interrupt handler.
    30183 *
     
    30688        istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
    30789            istate->r3, istate->r4, istate->r5, istate->r6);
    308 }
    309 
    310 /** Returns the mask of active interrupts. */
    311 static inline uint32_t gxemul_irqc_get_sources(void)
    312 {
    313         return *((uint32_t *) gxemul_irqc);
    314 }
    315 
    316 /** Interrupt Exception handler.
    317  *
    318  * Determines the sources of interrupt and calls their handlers.
    319  */
    320 static void irq_exception(int exc_no, istate_t *istate)
    321 {
    322         uint32_t sources = gxemul_irqc_get_sources();
    323         unsigned int i;
    324        
    325         for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
    326                 if (sources & (1 << i)) {
    327                         irq_t *irq = irq_dispatch_and_lock(i);
    328                         if (irq) {
    329                                 /* The IRQ handler was found. */
    330                                 irq->handler(irq);
    331                                 spinlock_unlock(&irq->lock);
    332                         } else {
    333                                 /* Spurious interrupt.*/
    334                                 printf("cpu%d: spurious interrupt (inum=%d)\n",
    335                                     CPU->id, i);
    336                         }
    337                 }
    338         }
    33990}
    34091
     
    385136#endif
    386137
     138/** Interrupt Exception handler.
     139 *
     140 * Determines the sources of interrupt and calls their handlers.
     141 */
     142static void irq_exception(int exc_no, istate_t *istate)
     143{
     144        machine_irq_exception(exc_no, istate);
     145}
     146
    387147/** Initializes exception handling.
    388148 *
  • kernel/arch/arm32/src/interrupt.c

    r7038f55 r6ac14a70  
    3636#include <arch/asm.h>
    3737#include <arch/regutils.h>
    38 #include <arch/drivers/gxemul.h>
     38#include <arch/machine.h>
    3939#include <ddi/irq.h>
    4040#include <ddi/device.h>
     
    4343/** Initial size of a table holding interrupt handlers. */
    4444#define IRQ_COUNT 8
    45 
    46 static irq_t gxemul_timer_irq;
    4745
    4846/** Disable interrupts.
     
    5351{
    5452        ipl_t ipl = current_status_reg_read();
    55        
     53
    5654        current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
    5755       
     
    6664{
    6765        ipl_t ipl = current_status_reg_read();
    68        
     66
    6967        current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
    7068       
     
    9290}
    9391
    94 /** Starts gxemul Real Time Clock device, which asserts regular interrupts.
    95  *
    96  * @param frequency Interrupts frequency (0 disables RTC).
    97  */
    98 static void gxemul_timer_start(uint32_t frequency)
    99 {
    100         *((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
    101             = frequency;
    102 }
    103 
    104 static irq_ownership_t gxemul_timer_claim(irq_t *irq)
    105 {
    106         return IRQ_ACCEPT;
    107 }
    108 
    109 /** Timer interrupt handler.
    110  *
    111  * @param irq Interrupt information.
    112  * @param arg Not used.
    113  */
    114 static void gxemul_timer_irq_handler(irq_t *irq)
    115 {
    116         /*
    117         * We are holding a lock which prevents preemption.
    118         * Release the lock, call clock() and reacquire the lock again.
    119         */
    120         spinlock_unlock(&irq->lock);
    121         clock();
    122         spinlock_lock(&irq->lock);
    123        
    124         /* acknowledge tick */
    125         *((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
    126             = 0;
    127 }
    128 
    12992/** Initialize basic tables for exception dispatching
    13093 * and starts the timer.
     
    13396{
    13497        irq_init(IRQ_COUNT, IRQ_COUNT);
     98        machine_timer_irq_start();
    13599       
    136         irq_initialize(&gxemul_timer_irq);
    137         gxemul_timer_irq.devno = device_assign_devno();
    138         gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
    139         gxemul_timer_irq.claim = gxemul_timer_claim;
    140         gxemul_timer_irq.handler = gxemul_timer_irq_handler;
    141        
    142         irq_register(&gxemul_timer_irq);
    143        
    144         gxemul_timer_start(GXEMUL_TIMER_FREQ);
    145100}
    146101
  • kernel/arch/arm32/src/mm/frame.c

    r7038f55 r6ac14a70  
    3636#include <mm/frame.h>
    3737#include <arch/mm/frame.h>
    38 #include <arch/drivers/gxemul.h>
     38#include <arch/machine.h>
    3939#include <config.h>
    4040
     
    4545void frame_arch_init(void)
    4646{
    47         last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
     47        last_frame = machine_get_memory_size();
    4848       
    4949        /* All memory as one zone */
     
    5454        frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
    5555            BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
     56
     57        machine_frame_init();
    5658}
    5759
  • kernel/arch/arm32/src/start.S

    r7038f55 r6ac14a70  
    3636
    3737kernel_image_start:
    38        
     38
     39        # initialize Stack pointer for exception modes
     40        mrs r4, cpsr
     41        bic r4, r4, #0x1f
     42
     43        #FIQ Mode
     44        orr r3, r4, #0x11
     45        msr cpsr_c, r3
     46        ldr sp, =exc_stack
     47
     48        #IRQ Mode
     49        orr r3, r4, #0x12
     50        msr cpsr_c, r3
     51        ldr sp, =exc_stack
     52
     53        #ABORT Mode
     54        orr r3, r4, #0x17
     55        msr cpsr_c, r3
     56        ldr sp, =exc_stack
     57
     58        #UNDEFINED Mode
     59        orr r3, r4, #0x1b
     60        msr cpsr_c, r3
     61        ldr sp, =exc_stack
     62
    3963        # switch to supervisor mode
    40         mrs r3, cpsr
    41         bic r3, r3, #0x1f
    42         orr r3, r3, #0x13
     64        orr r3, r4, #0x13
    4365        msr cpsr_c, r3
    4466       
Note: See TracChangeset for help on using the changeset viewer.