See attached version, that should work on S12XD with 512k of flash. Smaller derivatives will run away, since your EraseFlash() routine tries to erase most of the flash, including areas that are not available on S12XD256 and lower. You need to review that code. You should find there erase of 3 x 128k flash arrays, followed by erase of last flash array sector by sector.
You copy to RAM routine is removed, instead standard startup routine is used to copy code to RAM.
I did small change in PRM file for P&E multilink. Your version should work, but it is enough to have RAMCode PLACEMENT defined, no need for dedicated RAMCodeSeg SEGMENT. You can place RAMCode to RAM SEGMENT.
Small change in your program and erase routines. Even on error, you shouldn't exit to flash while CCIF bit is cleared.
__PIC_SEG segment attribute is not required.
If you didn't manipulate PPAGE in your program/erase code, I would use __NEAR_SEG attribute to make RAM function called with JSR, which would save few bytes of code and few CPU cycles. But since PPAGE has to be manipulated, __NEAR_SEG is not used and PPAGE is automatically saved and restored in CALL and RTC instructions.
You second version doesn't seem to have program erase routines, only erase verify routine. You should easily fix that. Though erase verify command doesn't erase or program, flash still is not readable while erase verify command is in progress. So you should move that routine to RAM and not exit from RAM to flash while CCIF bit is zero.