1
/*
2
 * $Id$
3
 *
4
 * Copyright (C) 2003-2009 JNode.org
5
 *
6
 * This library is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful, but 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
14
 * License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this library; If not, write to the Free Software Foundation, Inc., 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 */
20
 
21
package org.jnode.vm;
22
23
import java.io.PrintWriter;
24
import java.io.StringWriter;
25
26
import org.jnode.assembler.ObjectResolver;
27
import org.jnode.security.JNodePermission;
28
import org.jnode.annotation.Inline;
29
import org.jnode.annotation.Internal;
30
import org.jnode.annotation.KernelSpace;
31
import org.jnode.annotation.MagicPermission;
32
import org.jnode.vm.classmgr.VmMethod;
33
import org.jnode.vm.classmgr.VmType;
34
import org.jnode.vm.scheduler.VmProcessor;
35
import org.jnode.vm.scheduler.VmThread;
36
import org.vmmagic.pragma.UninterruptiblePragma;
37
import org.vmmagic.unboxed.Address;
38
import org.vmmagic.unboxed.Extent;
39
import org.vmmagic.unboxed.ObjectReference;
40
import org.vmmagic.unboxed.Offset;
41
import org.vmmagic.unboxed.Word;
42
43
/**
44
 * Class that allows directy hardware access.
45
 *
46
 * @author epr
47
 */
48
@MagicPermission
49
public final class Unsafe {
50
51
    private static final JNodePermission GET_JUMP_TABLE_PERM = new JNodePermission(
52
        "getJumpTable");
53
54
    @MagicPermission
55
    public static class UnsafeObjectResolver extends ObjectResolver {
56
57
        public UnsafeObjectResolver() {
58
        }
59
60
        /**
61
         * @param object
62
         * @return int
63
         * @see org.jnode.assembler.ObjectResolver#addressOf32(Object)
64
         */
65
        public int addressOf32(Object object) {
66
            return ObjectReference.fromObject(object).toAddress().toInt();
67
        }
68
69
        /**
70
         * @param object
71
         * @return long
72
         * @see org.jnode.assembler.ObjectResolver#addressOf64(Object)
73
         */
74
        public long addressOf64(Object object) {
75
            return ObjectReference.fromObject(object).toAddress().toLong();
76
        }
77
    }
78
79
    /**
80
     * Gets the Super Classes Array of the given object.
81
     *
82
     * @param object
83
     * @return VmType[]
84
     */
85
    protected static native VmType[] getSuperClasses(Object object);
86
87
    /**
88
     * Sets a byte at a given memory address While count is greater then 1, the
89
     * address is incremented and the process repeats.
90
     *
91
     * @param memPtr
92
     * @param value
93
     * @param count
94
     */
95
    protected static native void setBytes(Address memPtr, byte value, int count);
96
97
    /**
98
     * Perform a bitwise AND of the byte at the given address and the given
99
     * value. While count is greater then 1, the address is incremented and the
100
     * process repeats.
101
     *
102
     * @param memPtr
103
     * @param value
104
     * @param count  The number of times to repeat this operation
105
     */
106
    protected static native void andByte(Address memPtr, byte value, int count);
107
108
    /**
109
     * Perform a bitwise OR of the byte at the given address and the given
110
     * value. While count is greater then 1, the address is incremented and the
111
     * process repeats.
112
     *
113
     * @param memPtr
114
     * @param value
115
     * @param count  The number of times to repeat this operation
116
     */
117
    protected static native void orByte(Address memPtr, byte value, int count);
118
119
    /**
120
     * Perform a bitwise XOR of the byte at the given address and the given
121
     * value While count is greater then 1, the address is incremented and the
122
     * process repeats.
123
     *
124
     * @param memPtr
125
     * @param value
126
     * @param count  The number of times to repeat this operation
127
     */
128
    protected static native void xorByte(Address memPtr, byte value, int count);
129
130
    /**
131
     * Sets a short at a given memory address While count is greater then 1, the
132
     * address is incremented and the process repeats.
133
     *
134
     * @param memPtr
135
     * @param value
136
     * @param count
137
     */
138
    protected static native void setShorts(Address memPtr, short value,
139
                                           int count);
140
141
    /**
142
     * Perform a bitwise AND of the short at the given address and the given
143
     * value. While count is greater then 1, the address is incremented and the
144
     * process repeats.
145
     *
146
     * @param memPtr
147
     * @param value
148
     * @param count  The number of times to repeat this operation
149
     */
150
    protected static native void andShort(Address memPtr, short value, int count);
151
152
    /**
153
     * Perform a bitwise OR of the short at the given address and the given
154
     * value. While count is greater then 1, the address is incremented and the
155
     * process repeats.
156
     *
157
     * @param memPtr
158
     * @param value
159
     * @param count  The number of times to repeat this operation
160
     */
161
    protected static native void orShort(Address memPtr, short value, int count);
162
163
    /**
164
     * Perform a bitwise XOR of the short at the given address and the given
165
     * value While count is greater then 1, the address is incremented and the
166
     * process repeats.
167
     *
168
     * @param memPtr
169
     * @param value
170
     * @param count  The number of times to repeat this operation
171
     */
172
    protected static native void xorShort(Address memPtr, short value, int count);
173
174
    /**
175
     * Sets a char at a given memory address While count is greater then 1, the
176
     * address is incremented and the process repeats.
177
     *
178
     * @param memPtr
179
     * @param value
180
     * @param count
181
     */
182
    protected static native void setChars(Address memPtr, char value, int count);
183
184
    /**
185
     * Perform a bitwise AND of the char at the given address and the given
186
     * value. While count is greater then 1, the address is incremented and the
187
     * process repeats.
188
     *
189
     * @param memPtr
190
     * @param value
191
     * @param count  The number of times to repeat this operation
192
     */
193
    protected static native void andChar(Address memPtr, char value, int count);
194
195
    /**
196
     * Perform a bitwise OR of the char at the given address and the given
197
     * value. While count is greater then 1, the address is incremented and the
198
     * process repeats.
199
     *
200
     * @param memPtr
201
     * @param value
202
     * @param count  The number of times to repeat this operation
203
     */
204
    protected static native void orChar(Address memPtr, char value, int count);
205
206
    /**
207
     * Perform a bitwise XOR of the char at the given address and the given
208
     * value While count is greater then 1, the address is incremented and the
209
     * process repeats.
210
     *
211
     * @param memPtr
212
     * @param value
213
     * @param count  The number of times to repeat this operation
214
     */
215
    protected static native void xorChar(Address memPtr, char value, int count);
216
217
    /**
218
     * Sets an int at a given memory address While count is greater then 1, the
219
     * address is incremented and the process repeats.
220
     *
221
     * @param memPtr
222
     * @param value
223
     * @param count
224
     */
225
    protected static native void setInts(Address memPtr, int value, int count);
226
227
    /**
228
     * Perform a bitwise AND of the int at the given address and the given
229
     * value. While count is greater then 1, the address is incremented and the
230
     * process repeats.
231
     *
232
     * @param memPtr
233
     * @param value
234
     * @param count  The number of times to repeat this operation
235
     */
236
    protected static native void andInt(Address memPtr, int value, int count);
237
238
    /**
239
     * Perform a bitwise OR of the int at the given address and the given value.
240
     * While count is greater then 1, the address is incremented and the process
241
     * repeats.
242
     *
243
     * @param memPtr
244
     * @param value
245
     * @param count  The number of times to repeat this operation
246
     */
247
    protected static native void orInt(Address memPtr, int value, int count);
248
249
    /**
250
     * Perform a bitwise XOR of the int at the given address and the given value
251
     * While count is greater then 1, the address is incremented and the process
252
     * repeats.
253
     *
254
     * @param memPtr
255
     * @param value
256
     * @param count  The number of times to repeat this operation
257
     */
258
    protected static native void xorInt(Address memPtr, int value, int count);
259
260
    /**
261
     * Sets a 24-bit int at a given memory address While count is greater then
262
     * 1, the address is incremented and the process repeats.
263
     *
264
     * @param memPtr
265
     * @param value
266
     * @param count
267
     */
268
    protected static native void setInts24(Address memPtr, int value, int count);
269
270
    /**
271
     * Perform a bitwise AND of the 24-bit int at the given address and the
272
     * given value. While count is greater then 1, the address is incremented
273
     * and the process repeats.
274
     *
275
     * @param memPtr
276
     * @param value
277
     * @param count  The number of times to repeat this operation
278
     */
279
    protected static native void andInt24(Address memPtr, int value, int count);
280
281
    /**
282
     * Perform a bitwise OR of the 24-bit int at the given address and the given
283
     * value. While count is greater then 1, the address is incremented and the
284
     * process repeats.
285
     *
286
     * @param memPtr
287
     * @param value
288
     * @param count  The number of times to repeat this operation
289
     */
290
    protected static native void orInt24(Address memPtr, int value, int count);
291
292
    /**
293
     * Perform a bitwise XOR of the 24-bit int at the given address and the
294
     * given value While count is greater then 1, the address is incremented and
295
     * the process repeats.
296
     *
297
     * @param memPtr
298
     * @param value
299
     * @param count  The number of times to repeat this operation
300
     */
301
    protected static native void xorInt24(Address memPtr, int value, int count);
302
303
    /**
304
     * Sets a long at a given memory address While count is greater then 1, the
305
     * address is incremented and the process repeats.
306
     *
307
     * @param memPtr
308
     * @param value
309
     * @param count
310
     */
311
    protected static native void setLongs(Address memPtr, long value, int count);
312
313
    /**
314
     * Perform a bitwise AND of the long at the given address and the given
315
     * value. While count is greater then 1, the address is incremented and the
316
     * process repeats.
317
     *
318
     * @param memPtr
319
     * @param value
320
     * @param count  The number of times to repeat this operation
321
     */
322
    protected static native void andLong(Address memPtr, long value, int count);
323
324
    /**
325
     * Perform a bitwise OR of the long at the given address and the given
326
     * value. While count is greater then 1, the address is incremented and the
327
     * process repeats.
328
     *
329
     * @param memPtr
330
     * @param value
331
     * @param count  The number of times to repeat this operation
332
     */
333
    protected static native void orLong(Address memPtr, long value, int count);
334
335
    /**
336
     * Perform a bitwise XOR of the long at the given address and the given
337
     * value While count is greater then 1, the address is incremented and the
338
     * process repeats.
339
     *
340
     * @param memPtr
341
     * @param value
342
     * @param count  The number of times to repeat this operation
343
     */
344
    protected static native void xorLong(Address memPtr, long value, int count);
345
346
    /**
347
     * Sets a float at a given memory address While count is greater then 1, the
348
     * address is incremented and the process repeats.
349
     *
350
     * @param memPtr
351
     * @param value
352
     * @param count
353
     */
354
    protected static native void setFloats(Address memPtr, float value,
355
                                           int count);
356
357
    /**
358
     * Sets a double at a given memory address While count is greater then 1,
359
     * the address is incremented and the process repeats.
360
     *
361
     * @param memPtr
362
     * @param value
363
     * @param count
364
     */
365
    protected static native void setDoubles(Address memPtr, double value,
366
                                            int count);
367
368
    /**
369
     * Sets a Object at a given memory address While count is greater then 1,
370
     * the address is incremented and the process repeats.
371
     *
372
     * @param memPtr
373
     * @param value
374
     * @param count
375
     */
376
    protected static native void setObjects(Address memPtr, Object value,
377
                                            int count);
378
379
    /**
380
     * Fill the memory at the given memory address with size times 0 bytes.
381
     * <p/>
382
     * memPtr must be VmObject.SLOT_SIZE aligned
383
     * <p/>
384
     * size % VmObject.SLOT_SIZE must be 0
385
     *
386
     * @param memPtr
387
     * @param size
388
     */
389
    protected static native void clear(Address memPtr, Extent size);
390
391
    /**
392
     * Copy size bytes of memory from srcMemPtr to destMemPtr. The memory areas
393
     * must not overlap.
394
     *
395
     * @param srcMemPtr
396
     * @param destMemPtr
397
     * @param size
398
     */
399
    protected static native void copy(Address srcMemPtr, Address destMemPtr,
400
                                      Extent size);
401
402
    /**
403
     * Push an integer onto the execution stack
404
     *
405
     * @param value
406
     */
407
    protected static native void pushInt(int value);
408
409
    /**
410
     * Push a long onto the execution stack
411
     *
412
     * @param value
413
     */
414
    protected static native void pushLong(long value);
415
416
    /**
417
     * Push an Object onto the execution stack
418
     *
419
     * @param value
420
     */
421
    protected static native void pushObject(Object value);
422
423
    /**
424
     * Invoke the given method without any parameters
425
     *
426
     * @param method
427
     */
428
    protected static native void invokeVoid(VmMethod method);
429
430
    /**
431
     * Invoke the given method without any parameters
432
     *
433
     * @param method
434
     * @return int
435
     */
436
    protected static native int invokeInt(VmMethod method);
437
438
    /**
439
     * Invoke the given method without any parameters
440
     *
441
     * @param method
442
     * @return long
443
     */
444
    protected static native long invokeLong(VmMethod method);
445
446
    /**
447
     * Invoke the given method without any parameters
448
     *
449
     * @param method
450
     * @return Object
451
     */
452
    protected static native Object invokeObject(VmMethod method);
453
454
    /**
455
     * Halt the processor until the next interrupt arrives.
456
     */
457
    @Internal
458
    public static native void idle();
459
460
    /**
461
     * Cause the system to stop TODO Protect me again
462
     */
463
    @KernelSpace
464
    public static void die(String msg) {
465
        debug("Real panic: ");
466
        if (msg != null) {
467
            debug(msg);
468
        }
469
        die();
470
    }
471
472
    /**
473
     * Cause the system to stop TODO Protect me again
474
     */
475
    @KernelSpace
476
    private static native void die();
477
478
    /**
479
     * Print the given string on the screen.
480
     */
481
    @KernelSpace
482
    public static native void debug(String str);
483
484
    /**
485
     * Print the given value on the screen.
486
     */
487
    @KernelSpace
488
    public static native void debug(char value);
489
490
    /**
491
     * Print the given value on the screen.
492
     */
493
    @KernelSpace
494
    public static native void debug(int value);
495
496
    /**
497
     * Print the given value on the screen.
498
     */
499
    @KernelSpace
500
    public static native void debug(long value);
501
502
    /**
503
     * Print the given value on the screen.
504
     */
505
    public static final void debug(boolean value) {
506
        debug(value ? "true" : "false");
507
    }
508
509
    /**
510
     * Print the given value on the screen.
511
     */
512
    @KernelSpace
513
    public static native void debug(Address value);
514
515
    /**
516
     * Print the given value on the screen.
517
     */
518
    @KernelSpace
519
    public static native void debug(Word value);
520
521
    /**
522
     * Print the given value on the screen.
523
     */
524
    @KernelSpace
525
    public static native void debug(Extent value);
526
527
    /**
528
     * Print the given value on the screen.
529
     */
530
    @KernelSpace
531
    public static native void debug(Offset value);
532
533
    /**
534
     * Enable/Disable the kernel debugger.
535
     *
536
     * @return the previous enabled state.
537
     */
538
    public static native boolean setKdbEnabled(boolean on);
539
540
    /**
541
     * Is the kernel debugger enabled?
542
     */
543
    @KernelSpace
544
    public static native boolean isKdbEnabled();
545
546
    /**
547
     * Read a single byte from the kernel debugger input queue.
548
     *
549
     * @return The byte, or -1 if no data available.
550
     */
551
    @KernelSpace
552
    @Internal
553
    public static native int readKdbInput();
554
555
    /**
556
     * Initialize the new Thread.
557
     *
558
     * @param curThread
559
     * @param newStack
560
     * @param stackSize
561
     */
562
    @Internal
563
    public static native void initThread(VmThread curThread,
564
                                         Object newStack, int stackSize);
565
566
    protected static native int inPortByte(int portNr);
567
568
    protected static native int inPortWord(int portNr);
569
570
    protected static native int inPortDword(int portNr);
571
572
    protected static native void outPortByte(int portNr, int value);
573
574
    protected static native void outPortWord(int portNr, int value);
575
576
    protected static native void outPortDword(int portNr, int value);
577
578
    /**
579
     * Gets the minimum valid address in the addressspace of the current
580
     * architecture.
581
     *
582
     * @return Address
583
     */
584
    protected static native Address getMinAddress();
585
586
    /**
587
     * Gets the maximum valid address in the addressspace of the current
588
     * architecture.
589
     *
590
     * @return Address
591
     */
592
    protected static native Address getMaxAddress();
593
594
    /**
595
     * Gets the (inclusive) start address of the available memory.
596
     *
597
     * @return Address
598
     */
599
    protected static native Address getMemoryStart();
600
601
    /**
602
     * Gets the (exclusive) end address of the available memory.
603
     *
604
     * @return Address
605
     */
606
    protected static native Address getMemoryEnd();
607
608
    /**
609
     * Gets the (inclusive) start address of the kernel.
610
     *
611
     * @return Address
612
     */
613
    protected static native Address getKernelStart();
614
615
    /**
616
     * Gets the (exclusive) end address of the kernel.
617
     *
618
     * @return Address
619
     */
620
    protected static native Address getKernelEnd();
621
622
    /**
623
     * Gets the (inclusive) start address of the initial jarfile.
624
     *
625
     * @return Address
626
     */
627
    protected static native Address getInitJarStart();
628
629
    /**
630
     * Gets the (exclusive) end address of the initial jarfile.
631
     *
632
     * @return Address
633
     */
634
    protected static native Address getInitJarEnd();
635
636
    /**
637
     * Gets the (inclusive) start address of the boot heap.
638
     *
639
     * @return Address
640
     */
641
    protected static native Address getBootHeapStart();
642
643
    /**
644
     * Gets the (exclusive) end address of the boot heap.
645
     *
646
     * @return Address
647
     */
648
    protected static native Address getBootHeapEnd();
649
650
    /**
651
     * Gets information of the JNode kernel command line.
652
     *
653
     * @param destination If non-null, the commandline is copied into this array.
654
     * @return The maximum length of the command line
655
     */
656
    protected static native int getCmdLine(byte[] destination);
657
658
    /**
659
     * Trigger a yieldpoint
660
     */
661
    public static native void yieldPoint();
662
663
    /**
664
     * Gets the address of the system dependent jump table used for native
665
     * method indirection.
666
     *
667
     * @return The address of the system dependent jump table.
668
     */
669
    private static native Address getJumpTable0();
670
671
    /**
672
     * Gets the address of the system dependent jump table used for native
673
     * method indirection.
674
     *
675
     * @return The address of the system dependent jump table.
676
     */
677
    public static final Address getJumpTable() {
678
        final SecurityManager sm = System.getSecurityManager();
679
        if (sm != null) {
680
            sm.checkPermission(GET_JUMP_TABLE_PERM);
681
        }
682
        return getJumpTable0();
683
    }
684
685
    /**
686
     * Gets a jumptable entry. This method can only be called at runtime.
687
     *
688
     * @param index
689
     * @return The jumptable entry.
690
     */
691
    public static final Address getJumpTableEntry(int index) {
692
        final SecurityManager sm = System.getSecurityManager();
693
        if (sm != null) {
694
            sm.checkPermission(GET_JUMP_TABLE_PERM);
695
        }
696
        final int offset = index * Vm.getArch().getReferenceSize();
697
        return getJumpTable0().loadAddress(Offset.fromIntSignExtend(offset));
698
    }
699
700
    /**
701
     * Read CPU identification data.
702
     * <p/>
703
     * If id is null, this method will return the length of the id array that is
704
     * required to fit all data. If id is not null and long enough, it is filled
705
     * with all identification data.
706
     *
707
     * @param id
708
     * @return The required length of id.
709
     */
710
    @Internal
711
    public static native int getCPUID(int[] id);
712
713
    /**
714
     * List the current stacktrace on the kernel debug output.
715
     *
716
     * @throws UninterruptiblePragma
717
     */
718
    @Inline
719
    public static final void debugStackTrace() throws UninterruptiblePragma {
720
        VmProcessor.current().getArchitecture().getStackReader()
721
            .debugStackTrace();
722
    }
723
724
    /**
725
     * List the current stacktrace on the kernel debug output.
726
     *
727
     * @throws UninterruptiblePragma
728
     */
729
    @Inline
730
    public static final void debugStackTrace(String message, Throwable t) throws UninterruptiblePragma {
731
        Unsafe.debug(message);
732
        Unsafe.debug("\n");
733
        Unsafe.debugStackTrace(t);
734
    }
735
736
    /**
737
     * List the current stacktrace on the kernel debug output.
738
     *
739
     * @throws UninterruptiblePragma
740
     */
741
    @Inline
742
    public static final void debugStackTrace(Throwable t) throws UninterruptiblePragma {
743
        Unsafe.debug(t.getMessage());
744
        Unsafe.debug("\n");
745
746
        StringWriter w = new StringWriter();
747
        t.printStackTrace(new PrintWriter(w));
748
        Unsafe.debug(w.toString());
749
    }
750
751
    /**
752
     * List the current stacktrace on the kernel debug output.
753
     *
754
     * @throws UninterruptiblePragma
755
     */
756
    @Inline
757
    public static final void debugStackTrace(int max)
758
        throws UninterruptiblePragma {
759
        VmProcessor.current().getArchitecture().getStackReader()
760
            .debugStackTrace(max);
761
    }
762
763
    /**
764
     * return a nanosecond accurate timer based on the clock cycles
765
     * of the CPU
766
     *
767
     * @return nanosecond accurate time
768
     */
769
    public static native long getCpuCycles();
770
771
772
    /**
773
     * <b>DO NOT USE THIS METHOD</b> : it's bogus (especially for 64 bits CPU) and has not yet been tested
774
     *
775
     * @param codePtr
776
     * @param function
777
     * @param bufferPtr
778
     * @return not telling.
779
     * @deprecated this method is bogus.
780
     */
781
    public static native int callVbeFunction(Address codePtr, int function, Address bufferPtr);
782
}