Memory Map (S390): Difference between revisions
Jump to navigation
Jump to search
[unchecked revision] | [unchecked revision] |
Content added Content deleted
(Created page with "The memory map on the S390 is very simple, the first 1024 (or 8192, if on z/Arch) bytes are used as PSA area. The IPL is loaded just after that said PSA. == Detecting...") |
No edit summary |
||
Line 69: | Line 69: | ||
} |
} |
||
</source> |
</source> |
||
== See also === |
|||
=== Source code === |
|||
* [https://github.com/udos-project/UDOS/blob/3f446f4117d78fddf181f1df2927a9437fb08035/kernel/s390/cpu.c#L51 Example implementation (C)] |
|||
[[Category:S390]] |
Revision as of 19:05, 15 October 2021
The memory map on the S390 is very simple, the first 1024 (or 8192, if on z/Arch) bytes are used as PSA area. The IPL is loaded just after that said PSA.
Detecting memory
/* We are going to read in pairs of 1MiB and when we hit the memory limit we
* will instantly catch the program exception and stop counting, then it's just
* a matter of returning what we could count :) */
size_t s390_get_memsize(
void)
{
const uint8_t *probe = (const uint8_t *)0x0;
while(1) {
int r;
/* Do a "probe" read */
r = s390_address_is_valid(probe);
if(r != 0) {
kprintf("Done! %p\n", (uintptr_t)probe);
break;
}
kprintf("Memory %p\n", (uintptr_t)probe);
/* Go to next MiB */
probe += 1048576;
}
return (size_t)probe;
}
/* Check if an address is valid - this only catches program exceptions to
* determine if it's valid or not */
int s390_address_is_valid(
volatile const void *probe)
{
int r = 0;
S390_PSW_DEFAULT_TYPE old_pc_psw;
#if (MACHINE >= M_ZARCH)
struct s390x_psw pc_psw = {
0x00040000 | S390_PSW_AM64, S390_PSW_DEFAULT_AMBIT, 0,
(uint32_t)&&invalid
};
#else
struct s390_psw pc_psw = {
0x000C0000, (uint32_t)&&invalid + S390_PSW_DEFAULT_AMBIT
};
#endif
#if (MACHINE >= M_ZARCH)
memcpy(&old_pc_psw, (void *)S390_FLCEPNPSW, sizeof(struct s390x_psw));
memcpy((void *)S390_FLCEPNPSW, &pc_psw, sizeof(struct s390x_psw));
#else
memcpy(&old_pc_psw, (void *)S390_FLCPNPSW, sizeof(struct s390_psw));
memcpy((void *)S390_FLCPNPSW, &pc_psw, sizeof(struct s390_psw));
#endif
*((volatile const uint8_t *)probe);
goto end;
invalid:
r = -1;
end:
#if (MACHINE >= M_ZARCH)
memcpy((void *)S390_FLCEPNPSW, &old_pc_psw, sizeof(struct s390x_psw));
#else
memcpy((void *)S390_FLCPNPSW, &old_pc_psw, sizeof(struct s390_psw));
#endif
return r;
}