CHARCELL doesn't have sbs support, so disable it properly.
[maemo-rb.git] / lib / unwarminder / safe_read.S
blobd18bf49c0487b20b00ef729dacfb27cd75ee74c0
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2012 by Amaury Pouly
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18  * KIND, either express or implied.
19  *
20  ****************************************************************************/
21 #include "config.h"
23 .data
24 was_aborted:
25     .word   0
27 .section    .text.safe_read8
28 .type       safe_read8, %function
29 .global     safe_read8
30 @ bool safe_read8(uint8_t *addr, uint8_t *value)
31 safe_read8:
32     @ was_aborted = 0
33     ldr     r2, =was_aborted
34     mov     r3, #0
35     str     r3, [r2]
36     @ r0=*addr
37 safe_read8_faulty_addr:
38     ldrb    r0, [r0]
39     @ if(was_aborted)
40     ldr     r2, [r2]
41     cmp     r2, #1
42     @   return false;
43     moveq   r0, #0
44     bxeq    lr
45     @ if(value != NULL)
46     cmp     r1, #0
47     @   *value = r0
48     strneb  r0, [r1]
49     @ return true;
50     mov     r0, #1
51     bx      lr
52 .size       safe_read8, . - safe_read8
54 .section    .text.safe_read16
55 .type       safe_read16, %function
56 .global     safe_read16
57 @ bool safe_read16(uint16_t *addr, uint16_t *value)
58 safe_read16:
59     @ was_aborted = 0
60     ldr     r2, =was_aborted
61     mov     r3, #0
62     str     r3, [r2]
63     @ r0=*addr
64 safe_read16_faulty_addr:
65     ldrh    r0, [r0]
66     @ if(was_aborted)
67     ldr     r2, [r2]
68     cmp     r2, #1
69     @   return false;
70     moveq   r0, #0
71     bxeq    lr
72     @ if(value != NULL)
73     cmp     r1, #0
74     @   *value = r0
75     strneh  r0, [r1]
76     @ return true;
77     mov     r0, #1
78     bx      lr
79 .size       safe_read16, . - safe_read16
81 .section    .text.safe_read32
82 .type       safe_read32, %function
83 .global     safe_read32
84 @ bool safe_read32(uint32_t *addr, uint32_t *value)
85 safe_read32:
86     @ was_aborted = 0
87     ldr     r2, =was_aborted
88     mov     r3, #0
89     str     r3, [r2]
90     @ r0=*addr
91 safe_read32_faulty_addr:
92     ldr     r0, [r0]
93     @ if(was_aborted)
94     ldr     r2, [r2]
95     cmp     r2, #1
96     @   return false;
97     moveq   r0, #0
98     bxeq    lr
99     @ if(value != NULL)
100     cmp     r1, #0
101     @   *value = r0
102     strne   r0, [r1]
103     @ return true;
104     mov     r0, #1
105     bx      lr
106 .size       safe_read32, . - safe_read32
108 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
109 .section    .text.data_abort_handler
110 .type       data_abort_handler, %function
111 .global     data_abort_handler
112 data_abort_handler:
113     @ store minimal amount of registers
114     stmfd   sp!, {r0-r1}
115     @ compute faulty address
116     sub     r0, lr, #8
117     @ compare to safe_read8
118     ldr     r1, =safe_read8_faulty_addr
119     cmp     r0, r1
120     beq     1f
121     @ compare to safe_read16
122     ldr     r1, =safe_read16_faulty_addr
123     cmp     r0, r1
124     beq     1f
125     @ compare to safe_read32
126     ldr     r1, =safe_read32_faulty_addr
127     cmp     r0, r1
128     beq     1f
129     @ otherwise just normally to UIE
130     mov     r1, #2
131     b       UIE
133     @ set was_aborted
134     ldr     r1, =was_aborted
135     mov     r0, #1
136     str     r0, [r1]
137     @ restore registers
138     ldmfd   sp!, {r0-r1}
139     @ restore mode and jump back to the *next* instruction
140     subs    pc, lr, #-4
141 .size       data_abort_handler, . - data_abort_handler
142 #endif