os/kernelhwsrv/kernel/eka/klib/arm/ckdes8.cia
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\klib\arm\ckdes8.cia
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <e32cia.h>
sl@0
    19
#include <arm.h>
sl@0
    20
#include <kernel/kernel.h>
sl@0
    21
sl@0
    22
#ifdef __DES8_MACHINE_CODED__
sl@0
    23
sl@0
    24
GLREF_C void KUDesInfoPanicBadDesType();
sl@0
    25
GLREF_C void KUDesSetLengthPanicBadDesType();
sl@0
    26
GLREF_C void KUDesSetLengthPanicOverflow();
sl@0
    27
GLREF_C void Des8PanicBadDesType();
sl@0
    28
sl@0
    29
/**
sl@0
    30
Gets information about the specified descriptor.
sl@0
    31
sl@0
    32
If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
sl@0
    33
then the descriptor is read using user mode privileges.
sl@0
    34
sl@0
    35
@param aSrc The descriptor for which information is to be fetched.
sl@0
    36
@param aLength On return, set to the length of the descriptor.
sl@0
    37
@param aMaxLength On return, set to the maximum length of the descriptor,
sl@0
    38
                  or 1 if the descriptor is not writable.
sl@0
    39
sl@0
    40
@return Address of first byte in descriptor.
sl@0
    41
sl@0
    42
@panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
sl@0
    43
sl@0
    44
@pre  Do not call from User thread if in a critical section.
sl@0
    45
@pre  Interrupts must be enabled.
sl@0
    46
@pre  Kernel must be unlocked.
sl@0
    47
@pre  No fast mutex can be held.
sl@0
    48
@pre  Call in a thread context.
sl@0
    49
@pre  Can be used in a device driver.
sl@0
    50
*/
sl@0
    51
EXPORT_C __NAKED__ const TUint8* Kern::KUDesInfo(const TDesC8& /*aSrc*/, TInt& /*aLength*/, TInt& /*aMaxLength*/)
sl@0
    52
//
sl@0
    53
// Get information about a user descriptor
sl@0
    54
//
sl@0
    55
	{
sl@0
    56
	ASM_CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_INTERRUPTS_ENABLED|MASK_KERNEL_UNLOCKED|MASK_NOT_ISR|MASK_NOT_IDFC|MASK_NO_FAST_MUTEX);
sl@0
    57
	ASM_ASSERT_DATA_PAGING_SAFE		// todo: should this be ASM_ASSERT_PAGING_SAFE?
sl@0
    58
sl@0
    59
	asm("mrs ip, spsr ");
sl@0
    60
	asm("tst ip, #0x0f ");			// test for user or supervisor
sl@0
    61
	USER_MEMORY_GUARD_OFF(eq,r12,r12);
sl@0
    62
	asm("ldreqt r3, [r0], #4 ");	// if user r3=type/len
sl@0
    63
	USER_MEMORY_GUARD_ON(eq,r12,r12);
sl@0
    64
	asm("bne 1f ");					// branch if supervisor
sl@0
    65
	asm("bic ip, r3, #0xf0000000 ");	// ip=length
sl@0
    66
	asm("str ip, [r1] ");			// store length
sl@0
    67
	asm("mvn ip, #0 ");				// ip=max length=-1 if not writeable
sl@0
    68
	asm("cmp r3, #0x50000000 ");
sl@0
    69
	asm("bcs  " CSM_Z24KUDesInfoPanicBadDesTypev);
sl@0
    70
	asm("eor r3, r3, r3, lsr #1 ");
sl@0
    71
	asm("msr cpsr_flg, r3 ");
sl@0
    72
	USER_MEMORY_GUARD_OFF(,r1,r1);
sl@0
    73
	asm("ldrcst ip, [r0], #4 ");	// if writeable ip=max length and r0+=4
sl@0
    74
	asm("mov r1, r0 ");				// NB can't use ldrlet r0, [r0] - see ARM ARM
sl@0
    75
	asm("ldrlet r0, [r1] ");		// if pointer, r0=pointer field
sl@0
    76
	USER_MEMORY_GUARD_ON(,r1,r1);
sl@0
    77
sl@0
    78
	asm("2: ");
sl@0
    79
	asm("str ip, [r2] ");			// store max length
sl@0
    80
	asm("addeq r0, r0, #4 ");		// if BufCPtr, step r0 past TBufC length
sl@0
    81
	__JUMP(,lr);
sl@0
    82
sl@0
    83
	asm("1: ");
sl@0
    84
	asm("ldr r3, [r0], #4 ");		// r3=type/len
sl@0
    85
	asm("bic ip, r3, #0xf0000000 ");	// ip=length
sl@0
    86
	asm("str ip, [r1] ");			// store length
sl@0
    87
	asm("mvn ip, #0 ");				// ip=max length=-1 if not writeable
sl@0
    88
	asm("cmp r3, #0x50000000 ");
sl@0
    89
	asm("bcs  " CSM_Z24KUDesInfoPanicBadDesTypev);
sl@0
    90
	asm("eor r3, r3, r3, lsr #1 ");
sl@0
    91
	asm("msr cpsr_flg, r3 ");
sl@0
    92
	asm("ldrcs ip, [r0], #4 ");		// if writeable ip=max length and r0+=4
sl@0
    93
	asm("ldrle r0, [r0] ");			// if pointer, r0=pointer field
sl@0
    94
	asm("b 2b ");
sl@0
    95
	}
sl@0
    96
sl@0
    97
sl@0
    98
/**
sl@0
    99
Sets the length of the specified descriptor.
sl@0
   100
sl@0
   101
If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
sl@0
   102
then the length is written using user mode privileges.
sl@0
   103
sl@0
   104
@param aDes The descriptor.
sl@0
   105
@param aLength The new descriptor length.
sl@0
   106
sl@0
   107
@panic KERN-EXEC 34, if aDes is not a modifiable descriptor type.
sl@0
   108
@panic KERN-EXEC 35, if aLength is longer that the maximum length of aDes.
sl@0
   109
sl@0
   110
@pre  Do not call from User thread if in a critical section.
sl@0
   111
@pre  Interrupts must be enabled.
sl@0
   112
@pre  Kernel must be unlocked.
sl@0
   113
@pre  No fast mutex can be held.
sl@0
   114
@pre  Call in a thread context.
sl@0
   115
@pre  Can be used in a device driver.
sl@0
   116
sl@0
   117
@post The length of aDes is equal to aLength.
sl@0
   118
@post If aDes is a TPtr type then its maximum length is equal its new length.
sl@0
   119
*/
sl@0
   120
EXPORT_C __NAKED__ void Kern::KUDesSetLength(TDes8& /*aDes*/, TInt /*aLength*/)
sl@0
   121
//
sl@0
   122
// Set the length of a user descriptor, checking the length is O.K.
sl@0
   123
//
sl@0
   124
	{
sl@0
   125
	ASM_CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_INTERRUPTS_ENABLED|MASK_KERNEL_UNLOCKED|MASK_NOT_ISR|MASK_NOT_IDFC|MASK_NO_FAST_MUTEX);
sl@0
   126
	ASM_ASSERT_DATA_PAGING_SAFE
sl@0
   127
sl@0
   128
	asm("mrs ip, spsr ");
sl@0
   129
	asm("tst ip, #0x0f ");
sl@0
   130
	asm("bne  " CSM_ZN5TDes89SetLengthEi);
sl@0
   131
	USER_MEMORY_GUARD_OFF(,r12,r12);
sl@0
   132
	asm("ldrt r2, [r0], #4 ");			// r2=length/type, r0->maxlength
sl@0
   133
	asm("ldrt r3, [r0], #-4 ");			// r3=maxlength, r0->length/type
sl@0
   134
	asm("and r2, r2, #0xf0000000 ");	// r2=type field
sl@0
   135
	asm("cmp r2, #0x20000000 ");		// check for writeable descriptor
sl@0
   136
	USER_MEMORY_GUARD_ON(cc,r12,r12);
sl@0
   137
	asm("bcc  " CSM_Z29KUDesSetLengthPanicBadDesTypev);
sl@0
   138
	asm("cmp r1, r3 ");					// check length
sl@0
   139
	USER_MEMORY_GUARD_ON(hi,r12,r12);
sl@0
   140
	asm("bhi  " CSM_Z27KUDesSetLengthPanicOverflowv);
sl@0
   141
	asm("cmp r2, #0x40000000 ");		// check for EBufCPtr
sl@0
   142
	asm("orr r2, r2, r1 ");				// r2=type + new length
sl@0
   143
	asm("strt r2, [r0], #8 ");			// store new length, r0->ptr if EBufCPtr
sl@0
   144
	USER_MEMORY_GUARD_ON(ne,r12,r12);
sl@0
   145
	__JUMP(ne,lr);						// if not EBufCPtr finished
sl@0
   146
	asm("ldrt r2, [r0] ");				// r2=pointer to TBufCBase
sl@0
   147
	asm("strt r1, [r2] ");				// update length of TBufCBase
sl@0
   148
	USER_MEMORY_GUARD_ON(,r12,r12);
sl@0
   149
	__JUMP(,lr);
sl@0
   150
  	}
sl@0
   151
sl@0
   152
sl@0
   153
/**
sl@0
   154
Checks whether the specified name is a valid Kernel-side object name.
sl@0
   155
sl@0
   156
A name is invalid, if it contains non-ascii characters, or any of
sl@0
   157
the three characters: "*", "?", ":".
sl@0
   158
sl@0
   159
@param  aName The name to be checked.
sl@0
   160
sl@0
   161
@return KErrNone, if the name is valid; KErrBadName, if the name is invalid.
sl@0
   162
sl@0
   163
@pre Calling thread can be either in a critical section or not.
sl@0
   164
@pre Interrupts must be enabled.
sl@0
   165
@pre Kernel must be unlocked.
sl@0
   166
@pre No fast mutex can be held.
sl@0
   167
@pre Call in a thread context.
sl@0
   168
@pre Can be used in a device driver.
sl@0
   169
*/
sl@0
   170
#ifndef __KERNEL_MODE__
sl@0
   171
#error "TDesC is not 8-bit as __KERNEL_MODE__ is not defined (see e32cmn.h)"
sl@0
   172
#endif
sl@0
   173
__NAKED__ EXPORT_C TInt Kern::ValidateName(const TDesC& /*aName*/)
sl@0
   174
//
sl@0
   175
// Check for : * or ? in descriptor, return KErrBadName if found
sl@0
   176
//
sl@0
   177
	{
sl@0
   178
	ASM_CHECK_PRECONDITIONS(MASK_INTERRUPTS_ENABLED|MASK_KERNEL_UNLOCKED|MASK_NOT_ISR|MASK_NOT_IDFC|MASK_NO_FAST_MUTEX);
sl@0
   179
sl@0
   180
	asm("ldr r2, [r0], #4 ");			// r2=length/type
sl@0
   181
	asm("cmp r2, #0x50000000 ");
sl@0
   182
	asm("bcs " CSM_Z19Des8PanicBadDesTypev );
sl@0
   183
	asm("bics r3, r2, #0xF0000000 ");	// r3=length
sl@0
   184
	asm("moveq r0, #0 ");				// if length=0, return KErrNone
sl@0
   185
	__JUMP(eq,lr);
sl@0
   186
	asm("eor r2, r2, r2, lsr #1 ");
sl@0
   187
	asm("msr cpsr_flg, r2 ");
sl@0
   188
	asm("addcs r0, r0, #4 ");
sl@0
   189
	asm("ldrle r0, [r0] ");
sl@0
   190
	asm("addeq r0, r0, #4 ");			// r0=this.Ptr()
sl@0
   191
	asm("1: ");
sl@0
   192
	asm("ldrb r1, [r0], #1 ");			// r1=*r0++
sl@0
   193
	asm("cmp r1, #0x20 ");				// is it < 0x20 ?
sl@0
   194
	asm("rsbhss r2, r1, #0x7f ");		// if not, compare 0x7f with char
sl@0
   195
	asm("bls 2f ");						// if char < 0x20 or 0x7f <= char, error
sl@0
   196
	asm("cmp r1, #'*' ");				// is it *
sl@0
   197
	asm("cmpne r1, #':' ");				// if not, is it :
sl@0
   198
	asm("cmpne r1, #'?' ");				// if not, is it ?
sl@0
   199
	asm("subnes r3, r3, #1 ");			// if none of these, decrement length
sl@0
   200
	asm("bne 1b ");
sl@0
   201
	asm("2: ");
sl@0
   202
	asm("cmp r3, #0 ");					// reached end of string?
sl@0
   203
	asm("moveq r0, #0 ");				// if we did, return KErrNone
sl@0
   204
	asm("mvnne r0, #%a0" : : "i" (~KErrBadName));	// else return KErrBadName
sl@0
   205
	__JUMP(,lr);
sl@0
   206
	}
sl@0
   207
sl@0
   208
extern "C" EXPORT_C __NAKED__ TInt memicmp(const TAny* /*aLeft*/, const TAny* /*aRight*/, TUint /*aLength*/)
sl@0
   209
    {
sl@0
   210
	// r0 = aLeft, r1 = aRight, r2 = aLength
sl@0
   211
	asm("str r4, [sp, #-4]! ");
sl@0
   212
	asm("add r2, r2, #1 ");
sl@0
   213
sl@0
   214
	asm("1: ");
sl@0
   215
	asm("subs r2, r2, #1 ");
sl@0
   216
	asm("ldrneb r3, [r0], #1 ");
sl@0
   217
	asm("beq 0f ");
sl@0
   218
	asm("ldrb r4, [r1], #1 ");
sl@0
   219
	asm("orr ip, r3, #0x20 ");
sl@0
   220
	asm("cmp ip, #0x61 ");
sl@0
   221
	asm("rsbcss ip, ip, #0x7a ");
sl@0
   222
	asm("eors ip, r3, r4 ");
sl@0
   223
	asm("andcss ip, ip, #0xdf ");
sl@0
   224
	asm("beq 1b ");
sl@0
   225
	asm("orrcs r3, r3, #0x20 ");
sl@0
   226
	asm("cmp r4, #0x41 ");
sl@0
   227
	asm("rsbcss ip, r4, #0x5a ");
sl@0
   228
	asm("orrcs r4, r4, #0x20 ");
sl@0
   229
	asm("subs r0, r3, r4 ");
sl@0
   230
	asm("0: ");
sl@0
   231
	asm("moveq r0, #0 ");
sl@0
   232
	asm("ldr r4, [sp], #4 ");
sl@0
   233
	__JUMP(,lr);
sl@0
   234
	}
sl@0
   235
#endif
sl@0
   236
sl@0
   237
sl@0
   238
sl@0
   239