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

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents
children 7f92b23984dc
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@19515 9 // Returns physical addr of allocated himem chunk
pascal@19515 10 // Never fails (will use fallback if not enough mem/no xmm)
pascal@19515 11 // TODO: with proper cleanup it is possible to exit to DOS
pascal@19515 12 // even after XMM alloc - do dealloc, then exit...
pascal@19515 13 // don't forget to clean up the mess then, especially
pascal@19515 14 // XMM handle which is lost inside xmm_alloc()...
pascal@19515 15 // (don't drop fallback: use it if no XMM driver detected)
pascal@19515 16 static void read2mem(struct image_himem *m) {
pascal@19515 17 u32 buf=m->buf;
pascal@19515 18 while(1) {
pascal@19515 19 u8 xfer_buf[PAGE_SIZE];
pascal@19515 20 u16 size = read_image(m, xfer_buf, sizeof(xfer_buf));
pascal@19515 21 if(s16(size) <= 0) break;
pascal@19515 22 memcpy32(0, buf, seg(xfer_buf), ofs(xfer_buf), size);
pascal@19515 23 buf += size;
pascal@19515 24 m->remaining -= size;
pascal@19515 25 }
pascal@19515 26 }
pascal@19515 27
pascal@19515 28 extern "C" void sort(u32* v, int size);
pascal@19515 29
pascal@19515 30 // Returns ptr to mallocated zero-terminated list of physical page addrs
pascal@19515 31 // Never fails (will die if not enough mem)
pascal@19515 32 // Addresses are sorted in ascending order
pascal@19515 33 // static void malloc_vcpi(struct image_himem *m) {
pascal@19515 34 static void read2vcpi(struct image_himem *m) {
pascal@19515 35 u16 cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
pascal@19515 36 u32* bufv = (u32*)malloc_or_die((cnt+1)*sizeof(u32));
pascal@19515 37 // our malloc zeroes allocated mem: buf[cnt]=0;
pascal@19515 38 // Allocate pages, storing addrs in addrbuf
pascal@19515 39 {for(int i=0;i<cnt;i++) {
pascal@19515 40 u32 v;
pascal@19515 41 asm {
pascal@19515 42 db 66h
pascal@19515 43 xor dx,dx
pascal@19515 44 mov ax,0DE04h
pascal@19515 45 int 67h
pascal@19515 46 db 66h
pascal@19515 47 mov [word ptr v],dx
pascal@19515 48 }
pascal@19515 49 extern const char vcpi_alloc_err[];
pascal@19515 50 if(!v) die(vcpi_alloc_err);
pascal@19515 51 bufv[i] = v;
pascal@19515 52 }}
pascal@19515 53 // Sanitize addresses: ascending sort
pascal@19515 54 sort(bufv,cnt);
pascal@19515 55 m->bufv = bufv;
pascal@19515 56 //}
pascal@19515 57
pascal@19515 58 // Reads opened fd data into malloc_vcpi'ed memory
pascal@19515 59 // Dies if file isn't exactly 'size' bytes long
pascal@19515 60 // Needs intermediate buffer of exactly Nx4k bytes
pascal@19515 61 // static void read2vcpi(struct image_himem *m) {
pascal@19515 62 while(1) {
pascal@19515 63 u8 xfer_buf[PAGE_SIZE];
pascal@19515 64 u16 size = read_image(m, xfer_buf, PAGE_SIZE);
pascal@19515 65 if(s16(size) <= 0 || !*bufv) break;
pascal@19515 66 m->remaining -= size;
pascal@19515 67 memcpy_vcpi(*bufv++, seg(xfer_buf), ofs(xfer_buf));
pascal@19515 68 }
pascal@19515 69 }
pascal@19515 70
pascal@19515 71 void init_vcpi() {
pascal@19515 72 heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
pascal@19515 73 get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
pascal@19515 74 }
pascal@19515 75
pascal@19515 76 int skip_xmmalloc;
pascal@19515 77 void load_image(struct image_himem *m) {
pascal@19515 78 no_exit++; // die() won't return to DOS
pascal@19515 79 m->remaining = m->size;
pascal@19515 80 m->buf = m->fallback;
pascal@19515 81 if(m->fallback < _1m) {
pascal@19515 82 read2mem(m);
pascal@19515 83 } else if(vcpi==0) {
pascal@19515 84 if (!skip_xmmalloc) {
pascal@19515 85 u32 v = xmm_alloc(m->size);
pascal@19515 86 if(v) m->buf = v;
pascal@19515 87 }
pascal@19515 88 read2mem(m);
pascal@19515 89 } else {
pascal@19515 90 //malloc_vcpi(m);
pascal@19515 91 read2vcpi(m);
pascal@19515 92 }
pascal@19515 93 if(m->remaining) die("Read error");
pascal@19515 94 //break iso case close(m->fd);
pascal@19515 95 }
pascal@19515 96