wok annotate linld/stuff/src/HIMEM.CPP @ rev 19873

linld/tazboot: fix 286 case
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Mar 31 09:17:01 2017 +0200 (2017-03-31)
parents 76087975885f
children 9e8f9b54bd83
rev   line source
pascal@19515 1 // This file is distributed under GPL
pascal@19515 2 //
pascal@19515 3 // High mem handling routines
pascal@19515 4 // C++ part of VCPI madness is here
pascal@19515 5
pascal@19515 6 #include "crtl.h"
pascal@19515 7 #include "common.h"
pascal@19515 8
pascal@19571 9 struct image_himem pm;
pascal@19571 10 struct image_himem initrd;
pascal@19580 11 int skip_alloc;
pascal@19571 12
pascal@19571 13 // Called from inside kernel just before rm->pm
pascal@19571 14 // _loadds _saveregs: done by hand
pascal@19571 15 void far last_ditch() {
pascal@19571 16 cli(); // we start doing *really* destructive things to DOS/BIOS
pascal@19571 17 // it means: do not even try to enable ints
pascal@19571 18 // or call BIOS services after this
pascal@19571 19 asm {
pascal@19571 20 push ds
pascal@19571 21 push cs
pascal@19571 22 pop ds
pascal@19571 23 #ifndef NO386
pascal@19571 24 pusha
pascal@19571 25 #else
pascal@19571 26 push ax
pascal@19571 27 push bx
pascal@19571 28 push cx
pascal@19571 29 push dx
pascal@19571 30 #endif
pascal@19571 31 }
pascal@19571 32 struct image_himem *m = &pm;
pascal@19637 33 vm2rm();
pascal@19636 34 if(((u16 *)&m->fallback)[1] >= 0x10) m->fallback = _1m; // >= _1m ?
pascal@19580 35 if(m->bufv==0) {
pascal@19571 36 // Move kernel
pascal@19571 37 memcpy_image(m);
pascal@19571 38 // Move initrd
pascal@19571 39 memcpy_image(&initrd);
pascal@19571 40 } else { //vcpi
pascal@19571 41 // Move kernel
pascal@19571 42 // 'Gathering' copy in chunks of PAGE_SIZE
pascal@19571 43 // No risk of overlapping: kernel is copied from above to 1m mark
pascal@19571 44 m->size = initrd.size = PAGE_SIZE;
pascal@19571 45 u32 *p = m->bufv;
pascal@19571 46 reset_bufv(p);
pascal@19571 47 if (p) do {
pascal@19571 48 m->buf = *p;
pascal@19571 49 memcpy_image(m);
pascal@19571 50 next(p); m->fallback+=PAGE_SIZE;
pascal@19571 51 } while(*p);
pascal@19571 52 // Move initrd
pascal@19571 53 m = &initrd;
pascal@19571 54 if(m->fallback) {
pascal@19571 55 // This is tricky: copy initrd backwards to reduce
pascal@19571 56 // risk of overlapping: use the fact that initrd is copied
pascal@19571 57 // to the very top of ram
pascal@19571 58 // (overlapping still can happen with more than 256mb ram)
pascal@19571 59 // (generic solution for this overwrite problem, anyone?)
pascal@19571 60 p=m->bufv;
pascal@19571 61 reset_bufv(p);
pascal@19571 62 do {
pascal@19571 63 next(p); m->fallback+=PAGE_SIZE;
pascal@19571 64 } while(*p);
pascal@19571 65 do {
pascal@19571 66 prev(p); m->fallback-=PAGE_SIZE;
pascal@19571 67 m->buf = *p;
pascal@19571 68 memcpy_image(m);
pascal@19571 69 } while(p != m->bufv);
pascal@19571 70 }
pascal@19571 71 }
pascal@19571 72 asm {
pascal@19571 73 #ifndef NO386
pascal@19571 74 popa
pascal@19571 75 #else
pascal@19571 76 pop dx
pascal@19571 77 pop cx
pascal@19571 78 pop bx
pascal@19571 79 pop ax
pascal@19571 80 #endif
pascal@19571 81 pop ds
pascal@19571 82 }
pascal@19571 83 }
pascal@19571 84
pascal@19515 85 void load_image(struct image_himem *m) {
pascal@19515 86 no_exit++; // die() won't return to DOS
pascal@19515 87 m->remaining = m->size;
pascal@19562 88 m->buf = m->fallback;
pascal@19562 89 u32 buf;
pascal@19538 90 u32* bufv= &buf;
pascal@19580 91 if(((u16 *)&m->fallback)[1] >= 0x10 && !skip_alloc) { // >= _1m ?
pascal@19538 92 if(vcpi) {
pascal@19562 93 bufv = malloc_bufv_or_die(m); // update m->bufv
pascal@19515 94 }
pascal@19580 95 else {
pascal@19562 96 xmm_alloc(m); // update m->buf
pascal@19538 97 }
pascal@19515 98 }
pascal@19562 99 buf = m->buf;
pascal@19538 100 do {
pascal@19538 101 u8 xfer_buf[PAGE_SIZE];
pascal@19571 102 u16 size;
pascal@19571 103 if(s16(size = read_image(m, xfer_buf, PAGE_SIZE)) <= 0) break;
pascal@19571 104 storepage(bufv, ofs(xfer_buf));
pascal@19571 105 if (bufv != &buf) next(bufv);
pascal@19538 106 buf += size;
pascal@19538 107 } while (*bufv);
pascal@19515 108 if(m->remaining) die("Read error");
pascal@19538 109 close(m->fd2close);
pascal@19515 110 }