1*e72ddb44Sderaadt /* $OpenBSD: memprobe.c,v 1.2 2021/01/28 18:54:50 deraadt Exp $ */
243d589dfSmlarkin
343d589dfSmlarkin /*
443d589dfSmlarkin * Copyright (c) 1997-1999 Michael Shalayeff
543d589dfSmlarkin * Copyright (c) 1997-1999 Tobias Weingartner
643d589dfSmlarkin * All rights reserved.
743d589dfSmlarkin *
843d589dfSmlarkin * Redistribution and use in source and binary forms, with or without
943d589dfSmlarkin * modification, are permitted provided that the following conditions
1043d589dfSmlarkin * are met:
1143d589dfSmlarkin * 1. Redistributions of source code must retain the above copyright
1243d589dfSmlarkin * notice, this list of conditions and the following disclaimer.
1343d589dfSmlarkin * 2. Redistributions in binary form must reproduce the above copyright
1443d589dfSmlarkin * notice, this list of conditions and the following disclaimer in the
1543d589dfSmlarkin * documentation and/or other materials provided with the distribution.
1643d589dfSmlarkin *
1743d589dfSmlarkin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1843d589dfSmlarkin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1943d589dfSmlarkin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2043d589dfSmlarkin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2143d589dfSmlarkin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2243d589dfSmlarkin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2343d589dfSmlarkin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2443d589dfSmlarkin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2543d589dfSmlarkin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2643d589dfSmlarkin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2743d589dfSmlarkin * SUCH DAMAGE.
2843d589dfSmlarkin *
2943d589dfSmlarkin */
3043d589dfSmlarkin
3143d589dfSmlarkin #include <sys/param.h>
3243d589dfSmlarkin #include <machine/biosvar.h>
3343d589dfSmlarkin #include <dev/isa/isareg.h>
3443d589dfSmlarkin #include <stand/boot/bootarg.h>
3543d589dfSmlarkin #include "libsa.h"
3643d589dfSmlarkin
3743d589dfSmlarkin u_int cnvmem, extmem; /* XXX - compatibility */
3843d589dfSmlarkin
39*e72ddb44Sderaadt extern bios_memmap_t bios_memmap[64]; /* This is easier */
4043d589dfSmlarkin
4143d589dfSmlarkin void
dump_biosmem(bios_memmap_t * tm)4243d589dfSmlarkin dump_biosmem(bios_memmap_t *tm)
4343d589dfSmlarkin {
4443d589dfSmlarkin register bios_memmap_t *p;
4543d589dfSmlarkin register u_int total = 0;
4643d589dfSmlarkin
4743d589dfSmlarkin if (tm == NULL)
4843d589dfSmlarkin tm = bios_memmap;
4943d589dfSmlarkin
5043d589dfSmlarkin for (p = tm; p->type != BIOS_MAP_END; p++) {
5143d589dfSmlarkin printf("Region %ld: type %u at 0x%llx for %uKB\n",
5243d589dfSmlarkin (long)(p - tm), p->type, p->addr,
5343d589dfSmlarkin (u_int)(p->size / 1024));
5443d589dfSmlarkin
5543d589dfSmlarkin if (p->type == BIOS_MAP_FREE)
5643d589dfSmlarkin total += p->size / 1024;
5743d589dfSmlarkin }
5843d589dfSmlarkin
5943d589dfSmlarkin printf("Low ram: %dKB High ram: %dKB\n", cnvmem, extmem);
6043d589dfSmlarkin printf("Total free memory: %uKB\n", total);
6143d589dfSmlarkin }
6243d589dfSmlarkin
6343d589dfSmlarkin int
mem_limit(long long ml)6443d589dfSmlarkin mem_limit(long long ml)
6543d589dfSmlarkin {
6643d589dfSmlarkin register bios_memmap_t *p;
6743d589dfSmlarkin
6843d589dfSmlarkin for (p = bios_memmap; p->type != BIOS_MAP_END; p++) {
6943d589dfSmlarkin register int64_t sp = p->addr, ep = p->addr + p->size;
7043d589dfSmlarkin
7143d589dfSmlarkin if (p->type != BIOS_MAP_FREE)
7243d589dfSmlarkin continue;
7343d589dfSmlarkin
7443d589dfSmlarkin /* Wholly above limit, nuke it */
7543d589dfSmlarkin if ((sp >= ml) && (ep >= ml)) {
7643d589dfSmlarkin bcopy (p + 1, p, (char *)bios_memmap +
7743d589dfSmlarkin sizeof(bios_memmap) - (char *)p);
7843d589dfSmlarkin } else if ((sp < ml) && (ep >= ml)) {
7943d589dfSmlarkin p->size -= (ep - ml);
8043d589dfSmlarkin }
8143d589dfSmlarkin }
8243d589dfSmlarkin return 0;
8343d589dfSmlarkin }
8443d589dfSmlarkin
8543d589dfSmlarkin int
mem_delete(long long sa,long long ea)8643d589dfSmlarkin mem_delete(long long sa, long long ea)
8743d589dfSmlarkin {
8843d589dfSmlarkin register bios_memmap_t *p;
8943d589dfSmlarkin
9043d589dfSmlarkin for (p = bios_memmap; p->type != BIOS_MAP_END; p++) {
9143d589dfSmlarkin if (p->type == BIOS_MAP_FREE) {
9243d589dfSmlarkin register int64_t sp = p->addr, ep = p->addr + p->size;
9343d589dfSmlarkin
9443d589dfSmlarkin /* can we eat it as a whole? */
9543d589dfSmlarkin if ((sa - sp) <= PAGE_SIZE && (ep - ea) <= PAGE_SIZE) {
9643d589dfSmlarkin bcopy(p + 1, p, (char *)bios_memmap +
9743d589dfSmlarkin sizeof(bios_memmap) - (char *)p);
9843d589dfSmlarkin break;
9943d589dfSmlarkin /* eat head or legs */
10043d589dfSmlarkin } else if (sa <= sp && sp < ea) {
10143d589dfSmlarkin p->addr = ea;
10243d589dfSmlarkin p->size = ep - ea;
10343d589dfSmlarkin break;
10443d589dfSmlarkin } else if (sa < ep && ep <= ea) {
10543d589dfSmlarkin p->size = sa - sp;
10643d589dfSmlarkin break;
10743d589dfSmlarkin } else if (sp < sa && ea < ep) {
10843d589dfSmlarkin /* bite in half */
10943d589dfSmlarkin bcopy(p, p + 1, (char *)bios_memmap +
11043d589dfSmlarkin sizeof(bios_memmap) - (char *)p -
11143d589dfSmlarkin sizeof(bios_memmap[0]));
11243d589dfSmlarkin p[1].addr = ea;
11343d589dfSmlarkin p[1].size = ep - ea;
11443d589dfSmlarkin p->size = sa - sp;
11543d589dfSmlarkin break;
11643d589dfSmlarkin }
11743d589dfSmlarkin }
11843d589dfSmlarkin }
11943d589dfSmlarkin return 0;
12043d589dfSmlarkin }
12143d589dfSmlarkin
12243d589dfSmlarkin int
mem_add(long long sa,long long ea)12343d589dfSmlarkin mem_add(long long sa, long long ea)
12443d589dfSmlarkin {
12543d589dfSmlarkin register bios_memmap_t *p;
12643d589dfSmlarkin
12743d589dfSmlarkin for (p = bios_memmap; p->type != BIOS_MAP_END; p++) {
12843d589dfSmlarkin if (p->type == BIOS_MAP_FREE) {
12943d589dfSmlarkin register int64_t sp = p->addr, ep = p->addr + p->size;
13043d589dfSmlarkin
13143d589dfSmlarkin /* is it already there? */
13243d589dfSmlarkin if (sp <= sa && ea <= ep) {
13343d589dfSmlarkin break;
13443d589dfSmlarkin /* join head or legs */
13543d589dfSmlarkin } else if (sa < sp && sp <= ea) {
13643d589dfSmlarkin p->addr = sa;
13743d589dfSmlarkin p->size = ep - sa;
13843d589dfSmlarkin break;
13943d589dfSmlarkin } else if (sa <= ep && ep < ea) {
14043d589dfSmlarkin p->size = ea - sp;
14143d589dfSmlarkin break;
14243d589dfSmlarkin } else if (ea < sp) {
14343d589dfSmlarkin /* insert before */
14443d589dfSmlarkin bcopy(p, p + 1, (char *)bios_memmap +
14543d589dfSmlarkin sizeof(bios_memmap) - (char *)(p - 1));
14643d589dfSmlarkin p->addr = sa;
14743d589dfSmlarkin p->size = ea - sa;
14843d589dfSmlarkin break;
14943d589dfSmlarkin }
15043d589dfSmlarkin }
15143d589dfSmlarkin }
15243d589dfSmlarkin
15343d589dfSmlarkin /* meaning add new item at the end of the list */
15443d589dfSmlarkin if (p->type == BIOS_MAP_END) {
15543d589dfSmlarkin p[1] = p[0];
15643d589dfSmlarkin p->type = BIOS_MAP_FREE;
15743d589dfSmlarkin p->addr = sa;
15843d589dfSmlarkin p->size = ea - sa;
15943d589dfSmlarkin }
16043d589dfSmlarkin
16143d589dfSmlarkin return 0;
16243d589dfSmlarkin }
16343d589dfSmlarkin
16443d589dfSmlarkin void
mem_pass(void)16543d589dfSmlarkin mem_pass(void)
16643d589dfSmlarkin {
16743d589dfSmlarkin bios_memmap_t *p;
16843d589dfSmlarkin
16943d589dfSmlarkin for (p = bios_memmap; p->type != BIOS_MAP_END; p++)
17043d589dfSmlarkin ;
17143d589dfSmlarkin addbootarg(BOOTARG_MEMMAP, (p - bios_memmap + 1) * sizeof *bios_memmap,
17243d589dfSmlarkin bios_memmap);
17343d589dfSmlarkin }
174